I'm building a mvc application from scratch. Currently i'm very in doubt where to put the mapping from domain entities to view models. I have the following project layout
MVC application
Bl Layer (per domain, so 1 for orders, 1 for customers etc)
Repository layer. Per table mostly.
For example, now I need to build a grid. The controller is called to get the grid on the screen for example on the Index page. Then the index page calls the BL layer that eventually calls the repositories to access the data from the database. Now my question is, where should I map the domain enities to the viewmodels? I could do this in the controller or in the BL layer. What are the pro's and con's?
You should keep mapper logic at BL in seperate class not at controllers. Thats mainly because Its not the responsibilty of your controller to do the mapping. There should be another class to handle this mapping responsibilty. That's what SRP principle says, I think.
Better you have a look on some Object Oriented design SOLID OOD Principles.
Related
I have a small ASP.NET API that exists in two separate projects. The API project holds my controller classes and request/response models. The Logic project holds business logic and database models.
If a user submits a request, lets say a BookRequest, to my endpoint, where is the best location to handle conversion to my Book database model? Originally I had planned to have the Book model take a BookRequest as a constructor, however that would create a cyclical dependency, as Logic would need to reference API. I could move the RequestModels into the Logic project, however I feel those should live in the API project as they are specific to the controllers. The alternative would then be to have the API convert to the database model and pass that to the logic.
Is there a better method for handling this case while keeping the projects seperate?
To avoid the cyclical dependency you described you may want to consider breaking things out into a third project, with its own models. The problem comes in because your 'Logic' project maintains both your business logic and database models.
A simple example would be:
API with API-Models <--> Business Logic with DTOs <--> DAL with DB Models / Entities
In this example the Business Logic layer would handle the translation of API Models to DTOs (Data Transfer Objects), and DTOs to values returned from the DAL (Data Access Layer).
Consider researching common architecture patterns to find one that may fit your needs. A common pattern I often use is the Clean Architecture.
Here is a link to Microsoft Architecture Patterns documentation:
https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures
I have a Solution with one project is Entity Framework and have my ASP MVC project, I looking for some advice or opinion about the idea of create in top of my POCO objects and the DBContext, a Business Logic Layer with static classes that have the all the methods (example a ContactBLL class with GetContactByID, GetAllContacts, GetContactsByType) to allow the access to the model data and that can be accessed in the Controllers Actions. In that way I don't have to put the implementation code of this methods in Controller Actions methods, and it can be reusable invoking this methods in other Action Controllers. I will appreciate your opinion because it could guide me to respond a question I've asking to myself around a week based in the answer to this one (about where to define the DBContext and how use it).
You can create different projects according to core functionality.
Data Access Layer(DB context and repository etc.) you can make Project.DataAccess, it will have only db context class and repository.
Business Logic Layer(Project.Business) it will have business logic and make call to data access layer.
UI Layer(Project.WebUi) it is mvc project.
and so on.
for detail info you can see this http://prodinner.codeplex.com/ code
Create separate class library for your POCO,
then create another class library for your repository, this should
include only the interfaces needed for your repository
and the implementation will be on another class lib like Project.EF,
Project.NH which will include Entity Mapping, Migration, Repository
implementations. but in reality, chances are you wont be changing
your ORM lib once it was implemented because it will just cause you
a lot of headache(just my 2cents).
you'll create your business layer(class lib) and
web project as separate lib. Models folder of your MVC project will contain your ViewModels.
this is what Im using right now and of course not the best structure, it just something that Im happy with :). hope it helps.
In general, there are four standard projects in a ASP.NET MVC - Entity Framework solution. They are 1) MVC, 2) Core/Business Logic Layer(BLL), 3) Data Access Layer/DBContext (DAL) and 4) Common/Utility.
Standard MVC project consists three main elements which are Model, View and Controller. However, middle to complex solution usually cuts off the Model element from MVC project and moves it back to BLL, we call it as ViewModel(POCO). Following this structure, MVC project is now responsible for employ/use the services from BLL and control the UI through controller.
Business Logic Layer (BLL) is the core of implementing business logic. It is responsible for serving request from the MVC project and work with DAL to persist data. As said above, BLL is the place to define ViewModel, its relations as well interface/ abstract class to support implementing design pattern. Viewmodel(POCO) is likely mapping one-one to data entity at DAL but we do not use the data entity directly on View. Following this structure will help to increase the customization on ViewModel like adding constrains
DAL is the place for DBContext and its data entities.
Common project consist of shared functions like Logging which is used in 1) 2) and 3)
Please read more at
https://www.codeproject.com/Articles/70061/Architecture-Guide-ASP-NET-MVC-Framework-N-tier-En
https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/
I have an application that is separated into 4 layers to keep code organized and be able to reuse it.
My layers are:
presentation layer: an mvc4 project
business layer: a c# library project whit the Business logic
Data layer: a c# library that contains all the linq to the db
model layer: a c# library that contains a edmx ef5 for my database
So the idea is that for each controller or our mvc project we have 1 business class and 1 data class. and if some functionality needs to make use of code on other class, they do at business logic layer (different business logic classes can create new instances of other business logic classes.)
The problem I was having is that I was creating too many DbContext and I was getting some errors and problems because of it. Like loosing the lazy loading on my BL layers or not been able to assign objects like list to other objects when they came from different DbContext.
For example, if I have a medic controller/logic/data and I use a patient logic/data to get a list of patient for today, I get an error when I try to do medic.patients = patienstList;
So what I need to do is use one DbContext per web request, so the DbContext will be created on the controller and injected to the logic layer and those will inject to other logic class or to the data classes?
How can I do it?
There are number of ways of doing IOC in MVC.
Example would Unity.. where you can register an instance of DBContext.
Of course if the lifetime of you IOC container every extends beyond web requests. your are in for nasty time.
Even if you think it is 1 Context per request that you need. Be very careful if you use ASP pipeline events and access DbContext, you may actually need 1 context per Thread. But if you are happy to say you access starts at MVC Controller level. Then you are looking for a way to handle inversion of control only.
Unity from microsoft
dependency injection docu
https://unity.codeplex.com/documentation
IMHO the Business Object should not have to use another Business Object because that violates the Single Responsibility Principle.
The Data Layer object should be able to do everything the Business Object needs it to.
So you should write methods in the Business Layer Object and Data Layer Object method GetPatientsForMedic.
You may say "but the Hospitals Business Object can get me a list of Hospitals really easily". That is not it's job, because you said it's job is to service the Hospitals controller.
HOWEVER the problem only happens when you pass a Hospital object from the HospitalsBO to the MedicBO. So don't.
On the Hospitals controller, write a method GetListOfHospitalIDsAndNames. Then, if you need a dropdown of hospitals, call that, and use the IDs and text names.
You can indeed share a DbContext between two Business Objects by sharing a Unit of Work. But you probably shouldn't.
However i'm no expert... i avoided these problems by having one GINORMOUS business object with everything in it. That is also a BAD THING.
I recently started doing web dev in C# and I am confused about MVP pattern with the concept of Domain Driven Design.
I was told by one of the seniors that the application is separated into 5 different layers. The hierachical structure is like this: View, Presenter, Service, Repository, Entity.
Here are my understandings for these different layers:
View: Representation of data that is being delivered to client
Presenter: Codebehind. Handles client's request and sends info to service
Serivce: Business logic layer. Manipulates data.
Repo: Not exactly sure what it does.
Entity: An unique object in the domain, and no two objects are ever the same unless they have the same identity (attributes)
So, are my descriptions correct? Can someone elaborate on that? Also, what does the Repo layer do? Does it handle db transaction?
This might not be purely MVP pattern but it seems like this is the state of the application and I am new to all these concepts. It would be great if someone can explain it to me in simpler terms. Thanks.
There are a flew conflicts in my experience.
View - The actual page that renders data. The code-behind will implement the Interface required for the View.
Presenter - No, not the code-behind. The code-behind will instantiate a Presenter. The code-behind implements the View interface, and instantiates a Presenter (and generally passes itself along), like so:
public class CodeBehindPage : System.Web.UI.Page, IViewInterface {
private Presenter myPresenter;
public CodeBehindPage() {
myPresenter = new Presenter(this); // Presenter will require IViewInterface
}
}
Service - Correct.
Repository - Correct, it handles database transactions (loading/saving/etc).
Entity - Correct. Entities are Database objects.
I don't prefer to combine MVP design pattern with N-Tier Architecture. What you have described is more likely about N-Tier Architecture. N-Tier is an architecture that creates tier between logics.
Mainly there are 3 logics, presentation logic (UI specific logic such as calculating height or width of a control), business logic (data manipulation, validation, etc) and data access (CRUD operation).
MVP design pattern itself only consist of Model, View and Presenter. The view and presenter, in N-Tier architecture is considered as presentation logic. Model is too general in N-Tier, it can include both business logic and data access. MVP are a design where the view is communicating with the code behind via event-driven. As example is Asp.Net and C# Winform. Another good design pattern is MVC which is used in ASP.Net MVC.
Now speaking of your understandings of layers:
View is the UI. In Asp.Net it is .aspx file. It is considered as Presentation Logic Layer in N-Tier
Presenter is the code behind. In Asp.Net it is .aspx.cs file. It is considered as Presentation Logic Layer in N-Tier
Service is good, it is considered as Business Logic Layer in N-Tier
Repository is data access. Its main purpose is to communicate with the data storage. It can be Xml, Flat file, CSV or commonly database. It is considered as Data Access Layer in N-Tier
Entity is an object, which purpose is modelling the data, and will be passed between the layer. There is also a principle of POCO, where your Entity should be made as simple as you can (only consist of Properties). Its main purpose so that your Entities can be used in any kind of layers.
Domain Driven Design itself is another concept. It is a concept of designing the application regarding to the business process requirement. Not based on data which is usually be done by most programmer.
I have an ASP.NET app with a three layer architecture:
Presentation layer: ASP.NET
Bussiness Layer: C# library.
Data Access Layer: C# library with
ADO.Net Entity Framework objects.
Some methods on Bussiness layer would return ADO.NET entity objects but, data access layer is not visible at Presentation layer I can't do that.
My question is: On a design view, Is it correct to expose Entity Objects in the Presentation Layer? I think I only have to link Data Layer library with ASP.NET app.
Thank you!
It's absolutely desirable to have your entity objects available for use and consumption in your presentation tier. That's what all the work is for.
Binding collection of objects to a grid/listview/dropdown
Splashing a single object (i.e. customer) onto a form for read/update/delete
This makes your life easier by far. Otherwise you'd have to pass string after int after double after string between your presentation and business layers.
These may be Entity objects or even your own POCO objects that were hydrated from the Entity objects.
I would even go so far as to say that your Entites should be in their own assembly separate from the DAL.
I suggest that you look into the concepts of View objects...or Data Transfer Objects (DTO). You might consider using a tool like AutoMapper or similar which will create a view specific domain object out of your entities. In general you may have screens that need an entity present to perform its work. But more often than not you will need to pass several different entities. In this case you are better off creating one DTO that contains all of these entities. By doing this you are adding a layer of separation between your presentation layer and your business layer. Often times your entities have more power than you might want to expose to your presentation layer. And...vice versa. Frequently you may need to get some UI messages out to the presentation layer based on some validation flagged in your business layer. Rather than make your ui more complex than it needs to be (by passing in your full entities) you can only pass in what the UI needs in the form of the DTO. Also, there is never a need for your business objects to care about anything specific to the presentation layer. I suggest that you not databind directly to anything as far back as the data access layer. Technically your presentation layer should know as little as possible about your business layer. In the case of MVP or MVC this is very easy to achieve by disconnecting the front end and the back end by way of this additional separation!
I think no, it is not, the best way to do that is to separate data classes from behavior, and reference only data classes in presentation level.The good approach I think to use WCF see this link
See Supervising Controller and Passive View
If you pass the Entity, you are essentially Supervising controller. Otherwise you are Passive View.
Supervising controller is less work, but less testable. Supervising Controller also says databinding is OK.
Passive view is testable but a LOT more work. No databinding. Lots of properties.
Typically I stick with Supervising Controller. You typically don't need that level of testability and it isn't worth the extra trouble.