Mapping Domain Models to View Models - asp.net-mvc

I'm starting from a point very similar to: Domain Entities, DTO, and View Models.
The advised use of DTOs to map between the domain model and the MVC's ViewModel seems consistent expectations. I seek details of how to bridge the domain model (Entity Framework-based project) to the WebAPI mvc project.
I'm starting with a project of simple POCOs (generated by EF PowerTools to reverse engineer my existent db) that I want to connect to an MVC4 WebAPI project.
I expect I'll be adding business logic to the baseline POCO project as my solution evolves and perhaps this is the crux of this issue. The business logic that transforms the POCOs into something that can be mapped to the MVC project.
Exactly how do I wire these projects together so i can start creating controllers in the MVC project that knows about the entities of the EF project? Automapper? Can we point to posts/docs where this specific feature of Automapper is employed?

You don't want controllers that knows about the EF entities - that's the whole point of this. :)
You yourself say that the DTOs should be used to map your domain to your view model, and then you ask "how can I bridge my domain model with the mvc controllers?". You've already answered this - with DTOs!
The DTO serves as a transport layer between complex business objects and models used to display a certain view. Both of these have special requirements that don't strictly relate to "just data" - hence using DTOs will give you a greater decoupling and separation of concerns.
If you don't decouple domain from view model, you will be forced to directly reference your EF objects in your view model code, which exposes unnecessary data and functions "up the chain".
Now, if you use WebAPI as a way to ship data then I think you could usually get away with sending the DTOs, since WebAPI data usually wouldn't be implementing view model logic. But YMMV of course, depending on how you plan to use your controllers.
For AutoMapper I'd say it's best to start with their own docs (they even use DTO examples in them): http://github.com/AutoMapper/AutoMapper/wiki/Getting-started

Related

MVC project setup at the enterprise level. What's expected?

By reading at several articles posted here, I get mismatched information about how to properly configure a project.
I am looking for advise about how the pros do it at the enterprise level.
I see different schools of though about this, some people design in a truly N-Tier fashion, others prefer to use EF Code First directly in the MVC application and have FAT models and sort of have one big MVC app with logical separation of concerns, etc.
So for a mid-size project this is my set up and I want to ask for your opinions about it.
MVC application
Models -- Here my models have just what the view needs, validation logic, etc. These models are designed to pass data between the controller and views only.
Controllers -- Call the service layer where business logic lives and gets domain models back if needed. Converts domain models into view models and vice-versa.
Service layer
This is were the business (domain) logic lives.
The service layer is also in charge of communicating with the data layer to perform CRUD operations.
The service layer returns domain models to the controller in the MVC application and also expects domain models when invoked.
Data Repository layer
The data layer is a thin wrapper around EF and performs CRUD operations.
usually I will have a Code First approach where entity models are created for me by EF.
I convert the EF code first models to domain models and return these to the service layer.
The data layer also expect domain models from the service layer that in turn I convert to EF code first models and persist to the DB.
Domain Model layer
These are the domain models that are used and shared thorough the applications layers.
What's best design?
What's expected at the enterprise level?
There's nothing particularly wrong with the approach you've laid out. However, I do see it as overly complex. Your repository layer, in particular, is a totally unnecessary level of abstraction. You could simply just roll the EF stuff into your service layer and call it a day. Having to convert the entity into a domain model and then to a view model, is frankly, a pain. Just map your entity to your view model and back.
The only thing you should really bear in mind is that ASP.NET MVC very loosely follows the MVC pattern. There's no such thing as a true MVC Model, and trying to force something like an entity class into that mold is a huge mistake. Your Model is the combination and interaction of your entity class, view models that represent that class, and the querying logic you tuck away in your service layer.
I would like you to suggest have these layers in your project ----
Entites Layer--
it should contains only all your poco classes in a model folder.Nothing else
Data Layer----
It should contain Db interactions logic.
Also your Dbcontext class should reside in this.
You may use Repository Pattern and unit of work pattern for better seperation of concern.Use dependency injection to resolve dependencies using Unity Container(there are many other container also available).Please have a look on these design pattern and container.there are many articles available on net for this.Simply go through them thoroughly.
Service Layer ----
It should contain only service methods to call into your controller as your controller should not directly talk to data Layer.Its a much better approach and prevent your business logic from being exposed to external attacks.
MVC Layer or UI layer ---
It should contain only the controllers whose work is to call services and business logics inside them.
and View folder where we have all the views to be shown to the end users.
Its a pretty big question.I hope may be u get some idea from this.

ASP.NET MVC - Model can have business logic?

I read a couple of articles which defines domain model (as in MVC) as something that holds business logic. I never considered a model to hold any methods other than the model properties.
I would like to know if actually there is a thought which supports having functions and business logic in the domain models.
Thanks in advance.
Of course business logic should be inside domain models. But, domain models are more than just entity framework entities. Domain models consists of many small classes which reflects business domain.
In my typical MVC application, I usually split some type of business logic into these (but not limited to):
ViewModels which responsible for model for view.
Controllers which is thin and responsible for application flow.
Simple business logic such as required field can exist as attribute within entity framework model or ViewModels.
Complex business logic such as place order, booking ticket are promoted to be its own class such as PlaceOrderOperation or PlaceOrderCommand.
Simple query logic might be inside the Controller or short extension method to DbSet<Entity> type.
Complex Query also promoted to its own class such as GetMostPorpularProductsQuery assuming that the query is complex.
Infrastructure components may be extension to Entity Framework or MVC components such as ActionFilter, CustomRoute, CustomTemplate or its own classes such as EncyptionHelpers etc.
Conclusion
Building domain Model is more than just creating classes prefix with BusinessLogic such as UserBusinessLogic or with Services such as UserServices. It should consists of many small classes which responsible for one thing. Of course, you would require some usage of design patterns, choice of frameworks, infrastructure components such as error handling, localization, caching, etc.
Welcome to the trade-off world. :)
An MVC Model can indeed have business logic. MVC responsibilities been discussed in more depth here and here is a discussion on anemic domain models - this might help clear things up for you?
From MSDN:
Models, which is provided for classes that represent the application
model for your MVC Web application. This folder usually includes code
that defines objects and that defines the logic for interaction with
the data store. Typically, the actual model objects will be in
separate class libraries. However, when you create a new application,
you might put classes here and then move them into separate class
libraries at a later point in the development cycle.
What might be confusing the issue is that many ASP.Net MVC implementations use View Models, which are classes used to transfer presentation tier data between View and Controller.
In a typical large project setup, we usually delete the Models folder, and instead move our EF data layer, Entities, and business / service logic into separate assemblies entirely.
Based on my experience best place to place business logic is layer between controllers and models. Try some popular patterns, like repository or tasks/commands.

Domain Entities, DTO, and View Models

I have an ASP.NET MVC 2 application with a POCO domain model and an NHibernate repository layer. My domain model has no awareness of my viewmodels so I use automapper to go from viewmodel to entity and vice/versa.
When I introduced WCF to my project (a late requirement), I started having to deal with disconnected objects. That is, I retrieve an entity from the database with NHibernate and once that entity is serialized it becomes disconnected and each child collection is loaded regardless of whether or not I plan on using it meaning I'm doing alot of unnecessary database work.
After reading up on this, I see that it is highly recommended that you not expose your entities outside of your domain project and you should instead use DTOs.
I see the reason for this but I'm having trouble figuring out how to implement it.
Do I map from viewmodel to DTO in ASP.NET MVC, send DTOs through the service layer, and map from DTO to entity in the service layer? Where should I define my DTOs?
I like to have my service layer keep entities encapsulated within it, and return/receive only DTOs. I keep the service contracts as well as the DTO's in a separate assembly which both the MVC project and the Service implementation reference.
Inside the service call implementation, the service maps dto's to entities, then does the interaction with repositories and other entities as it needs to.
On the app/mvc project I sometimes will get lazy and just use DTO's as the models for certain actions (especially CRUDy ones). If i need a projection or something like that, then I'll make a viewmodel and convert between DTO and viewmodel with automapper etc.
How exposed your entities are is a subject of much debate. Some people will push them all the way to the view/app layer. I prefer to keep them in the service layer. I find that when the entities leave the service layer, you find yourself doing business logic type stuff anywhere where they're interacted with, stuff that should probably reside in a service.
I treat my DTOs like ViewModels because the UI layer ( MVC app ) is requesting them. You could go Entity -> DTO -> ViewModel but I think thats over engineering if the only consumer of your service is an MVC application. If somehow the DTOs will actually be used for data and not simply screen specifications then you should probably use additional mapping.
I've also simply returned entities from my WCF layer and let the automatically generated proxy objects on the client be the DTO. The entities almost become DTOs because of the proxy classes and no business logic comes over to the client.
And of course, this is all "It Depends" what your architectural goals are. This question is borderline subjective and argumentative IMHO.
I like defining the DTO in the MVC project and then creating extension methods to transform from domain entity to DTO (and vice-versa).
The transformation would take place in the mvc functions.
I just wrote a post about a way of getting around all this DTO <-> DO transformation. Maybe you check it out http://codeblock.engio.net/?p=17

Working with MVC 2.0 and the Model in a separate assembly

I'm new to MVC and even though there is a lot (and I do mean a lot) of information out there that is very useful - it's proofing very difficult to get a clear understanding on how to achieve my exact requirements with MVC 2.0.
I would like to set up a solution as follows:
Provide a web UI using an MVC 2.0 project.
Use Linq to SQL classes project for data persistence.
I have a two separate code modules that will need to access the above Linq to SQL model - so I won't be able to include my Linq to SQL model directly in the MVC project itself.
Also I have a Business Logic layer in front of my Linq to SQL project.
My questions are:
How do I set up the Model part of my MVC application to point to my Linq to SQL project via my BLL?
How do I perform web app validation? Can I use MVC 2.0 Model Validation? If not what are the alternatives?
Finally (and slightly aside) - What is the ViewModel and how does this differ from the Model?
So many questions. But this is an exciting new technology and data access issues aside, everything else I've got to grips with very quickly and I think MVC 2.0 is fantastic.
Thanks for any pointers you can provide.
How do I set up the Model part of my
MVC application to point to my Linq to
SQL project via my BLL?
Typically you'd use a repository pattern for this. Your controller has a reference to your repository - the repository returns your domain objects from your database. The MVC app has no knowledge LINQ to SQL exists.
How do I perform web app validation?
Can I use MVC 2.0 Model Validation? If
not what are the alternatives?
Put view models in your MVC project. These view models may closely align with your domain models but their concern is to be the presentation model. Put your data annotations for validation on these view models - the MVC framework will automatically ensure validation occurs on these view models decorated with data annotations. It's pluggable so you could use alternatives - but with MVC 2, it's baked in fairly well and this includes client side validation.
Finally (and slightly aside) - What is
the ViewModel and how does this differ
from the Model?
I partially answered this one above. the shape of your domain models may not be the shape you need to display your views - view models are great to bridge this gap. Additionally, even if the shape does match exactly - view models are still a good idea so that you can put UI validation code there and other presentation meta-data on them (since you do not want anything related to presentation logic on your domain model).
Here's link for view model patterns.
Hope this helps.
You can add a reference to the objects exposed from your BLL assembly and use them as your Models.
When you want to add validation to classes that are generated use buddy classes.
A ViewModel is a custom-shaped aggregate of Model data. There is exactly one per View, as the ViewModel's purpose is to surface exactly the data needed by a particular View in a convenient and concise way.
An example might be a View that contains both Order and OrderDetail information. A ViewModel can hold internal references to the repositories and business objects for each type. Properties of the ViewModel merge together the data from these objects.
ViewModels will be useful in your case also because you want your Models to be in a separate assembly. You can apply the DataAnnotations to ViewModel properties for validation. You would make the "raw" business object models internal properties of your ViewModels, and expose public methods to retrieve and persist data.

How can I extend the Model in ASP.NET MVC and Entity Framework?

In my first ASP.NET MVC applications, the model was a simple O/R mapping between a table and the classes, managed by the Entity Framework.
Now I would like to add some meat to this skeleton, and introduce business methods for the generated classes. What is the recommended approch to this in ASP.NET MVC (with Entity Framework)? My favorite would be solution which also can be used in a service layer, with no ASP.NET MVC references, so that the same domain logic also could be reused in a desktop client.
Technically, I think it should be possible to extend the generated classes in a way which preserves the additional business logic even if the O/R classes need to be refreshed. (This is more a question related to the Entity Framework however.)
Edit: Many thanks for the contributions, and the information about the next version of Entity Framework (4.0). Building two sets of classes, one auto-generated to represent the data in the persistency layer and one for the actual business logic sounds interesting.
Within MVC.Net, the model is the least clearly defined part. In my opinion, it's basically the rest of your application (i.e. anything not related to the View or the Controller). The O/R Mapping part of your application should probably be outside of the "Model" also, as this is more of a data layer. The Model, should really deal in business objects and create views of your data to pass to the View.
There are lots of differing opinions on this, but I think it's best not to think of MVC.Net as traditional MVC Architecture.
If you are using EF v1.0 right now, the Entity Framework is very intrusive into your application, which means that you cannot create POCO very easily. The way you can extend your model is by using the partial class. So when you refresh your model, the partial class you did will still be valid. The Entity Framework team realizes this is a problem , and have improved this in next version (EF V4.0).
NHibernate is much more friendly and allow you easily extend your business logic.
I really think this blog post by Jeremy D. Miller is very good at pointing out the problem.
Abstract your Business Layer out into another project, then pass an instance of it onto your mvc controller using something like structure map. You can then call this Business Layer from your controller to retrieve your business entities (Model) and pass them on to the UI. This will allow you to resuse your Business Layer in your desktop application.
Not only meat but also some clothes and a style could be added to this project to make it seem chic. It depends on the time you have for the project. If you have time, I could suggest you to get a look to TDD and the frameworks that could be used with TDD such as Castle, NUnit, Moq etc.
As you mentioned a service layer is a must for any project but with these kinds of frameworks you could design your architecture more robust.

Resources