Asp.net-mvc – Domain Entities, DTO, and View Models

asp.net-mvcdomain-driven-designdtopocowcf

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?

Best Answer

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.