Thursday, March 11, 2010

Mapping Business Entities to Data Transfer Objects

DTOs???? Why???

Here is an example: You wish to open up some processing to external callers via a web-service. Should your business entities also become your data-contracts?

Well, in my opinion (and from what I am seeing on the Internet), the answer is no. The answer is two-fold: separation of concerns and stability of your webservice. Enter data-transfer-objects (DTOs).

Typically you create your DTO in your service interface layer (they layer where you write your web-service). Your business entities are hydrated from your repository by your resource access layer. The business logic layer processes requests, gets the business entities from the resource access layer and provides it to the service interface layer.

The service interface layer then converts the business entity object to the DTO and then passes it back over the wire to the client calling the webservice.

Why is this good? For one – if your business entity changes, your web-service does not have to change (a good thing, especially if your webservice is publically accessible) and if your business entity had extra methods, fields, etc, they dont get pushed down the wire as your DTO is typically a very simple and clean object.

Why this post?

Well it turns out that the mapping between business entity objects and DTOs can be very boring, time consuming, pain to maintain, etc….

Enter Automapper. Automapper is an open source CodePlex project that performs mapping between objects using conventions. So as long as your DTO objects and BE objects share the same property and field names, the transfer of data will be nice and simple.

The code couldnt be simpler:

Mapper.CreateMap<SourceClass, DestinationClass>();
DestinationClass destinationObject = Mapper.Map<SourceClass, DestinationClass>(sourceObject);

Automapper also supports flattening (taking a complex object and converting it to a simpler object).

1 comment:

Allan said...

Thanks for pointing out Automapper. This looks like a very useful tool.

I agree with your conclusion of separating concerns. The easy approach (just sending business entities over the wire) works but it starts to feel pretty ugly in WCF when you start adding [DataContract] attributes all over the entities layer.

I find that it is also very risky to refactor when you don't have DTOs as you need to be sure you aren't breaking the service contract by doing so.