February 25, 2010 .NET, AutoMapper, Frameworks
February 25, 2010 .NET, AutoMapper, Frameworks
The Problem
Have you ever faced need to write code, which looks like here:
Our scenario could be like:
We have our domain model which has Customer entity and we are going to show Customers in DataGrid, and for that we need much lighter object CustomerViewItem, list of which is bounded to the Grid.
As you see there are four lines of code which are just copying values from one object to another. Could also be that you will need to show up to 10-15 columns in you grid. What then?
Would you like to have something that will do mapping from Customer to the CustomerViewItem automatically?
Of course you do, especially if you have another situation like mapping of heavy data objects into DTO objects which are considered to be send though the wire.
AutoMapper
From the AutoMapper codeplex web page we see that “AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper’s established convention, almost zero configuration is needed to map two types.“, so in other words it provides the solution for our problem.
To get started go and download it here. It is standalone assembly, so you should not get difficulties with including reference to it in your project.
So in order to ask AutoMapper do dirty work instead of me, we need to add next line somewhere in the start of our code execution:
Mapper.CreateMap<Customer, CustomerViewItem>();
Once we have that we are done and we can use pretty nice code to get our mapped object:
Lets take a look on whole code base to see all about what I’m going to talk further:
And proving that all values has been mapped take a look on the picture:
More Complex Example 1 (Custom Map)
So far we know all to have extremely simple mapping. But what if we need something more complex, for example, CustomerViewItem should have FullName, which consists with First and Last names of Customer?
After I just added public string FullName { get; set; } to the CustomerViewItem and run my application in debug I got null value in that property. That is fine and is because AutoMapper doesn’t see any FullName property in Customer class. In order to “open eyes” all you need is just to change a bit our CreateMap process:
And results are immediately:
More Complex Example 2 (Flattening)
What if you have property Company of type Company:
and want to map it into CompanyName of the view class
How do you think what do you need to change in your mapping to make this work?
Answer: NOTHING. AutoMapper goes in deep of your classes and if names matches it will do mapping for you.
More Complex Example 3 (Custom type resolvers)
What if you have boolean property VIP in your Customer class:
and want to map it into string VIP and represent like “Y” or “N” instead
Well, we can solve this the same way we did for the FullName, but more appropriate way is to use custom resolvers.
So lets create customer resolver which will resolve VIP issue for us.
It looks like:
And only one line is needed for our CreateMap process:
.ForMember(cv => cv.VIP, m => m.ResolveUsing<VIPResolver>().FromMember(x => x.VIP));
More Complex Example 4 (Custom Formatters)
What if I want AutoMapper to use my custom formatting of the DateTime instead of just using ToString, when it does mapping from DateTime to String property?
Let say I want use ToLongDateString method to show birth date with fashion.
For that we add:
And making sure that AutoMapper knows where to use it:
.ForMember(cv => cv.DateOfBirth, m => m.AddFormatter<DateFormatter>());
So, now I’ve got:
Great, isn’t it? BirthDate is even in my native language.
I hope my article was interesting to read and it gave you ideas how you can utilize this new feature called “AutoMapper”.
Markdown | Result |
---|---|
*text* | text |
**text** | text |
***text*** | text |
`code` | code |
~~~ more code ~~~~ |
more code |
[Link](https://www.example.com) | Link |
* Listitem |
|
> Quote | Quote |
Great thing! Really! Thanks for mentioning it.
But how it will work if I have CustomerViewItem, which contains some CompanySimplification property, which have to mapped from more complex Company class?
I mean something like
public class Company
{
public int id { get; set;}
public string name { get; set; }
public Person CEO { get; set;}
}
public class CompanySimplification
{
public int id { get; set;}
public string name { get; set;}
}
public class CustomerViewItem
{
public string name { get; set; }
public CompanySimplification company { get; set;}
}
I hope you've got an idea.
Ok, I have researched this issue myself. Surprisingly, it allows such a use case! I'm going to ask my PM to use AutoMapper in our project. Thanks again for this post!!!
Hey, thanks.. and point to my blog… maybe I'll migrate to your company in near future with better salary… :)
if I have an opportunity – I'll definitely do this ;)