Today I’ll post about a practice of which I’m a big fan, namely DTOs (or view models, if you wish) and mappers.
DTO stands for Data Transfer Object, and its sole responsibility is to transfer data between layers. A view model is essentially the same thing, it’s a mostly primitive object to show data to the user and gather information from her/him, tightly coupled to a single view. And a mapper is what does the translation between your entities and your DTOs.
One could question the point of adding yet another layer to an application. It’s true, you can live without another mini-model living in your views and the added complexity of mapping everything back and forth. But allowing entities to reach the user interface layer is not the best idea ever. Let me show an example.
I’ve deliberately created a crappy design here, but crappy design isn’t that uncommon, and using code-generators (e.g. an ORM which is capable to create entities from a database) you won’t even know this happened. So it’s our everyday User and Product entities, except a little twist: Password is stored as plain text (very uncommon, you’d say) and someone, someday for some unknown business reason has added a column to the Product table called LastBuyer, and made a foreign key relationship with the User table. Entity Framework would generate something like this:
It isn’t tragic yet, but under the right circumstances it’s a receipt for disaster. Imagine that you’d like to create a nice REST API for your system to work on mobile devices. Just create a new ASP.NET MVC Web API project and add a service for handling Product entities. If you change nothing (use the default serializer) then you’ll end up publishing some of your unlucky users’ usernames and passwords (and a lot of related information) in this nice format:
As you see, only two things were needed: crappy design and ignorance – both can be found in the wild. Now how can we prevent such situations?
The basic principle is to never, ever send your entities to the end user. One technic to deal with this is to employ DTOs. In our case, we would use a lightweight class called ProductDTO. If we’d really like to follow our business model, we can create something like this:
There’s no chance for the password to slip through this, and we only show what is really needed, and nothing else. Of course the above example of leaking the user’s password is rather serious and grave, and issues like this are hopefully really rare. I did it just to illustrate my point.
Now my beloved part, the mappers. Here’s a fairly simple implementation:
You see it’s super easy, adheres to the Single Responsibility Principle, testable and all that stuff. And even better, for simple cases like this, you can auto-generate all your mappers with e.g. AutoMapper.
And with a simple LINQ query you can create something as elegant as this:
As they are really easy to implement, you could even auto-generate the tedious work of creating mappers there’s really no reason not to employ this pattern. To be more accurate: there’s no reason to present business entities to your end users.