Hi there,
Hope you are doing great, I have another topic I would like to discuss with you! It’s Automapper. You may have heard of it and you may have already used it but I think there will be a little take away for everyone in this post. This will be the first part of the post
Today we are going to talk about:
1) How we can use Visual studio Nuget to get Automapper in our MVC 3 solution.
2) How we can map out LINQ data classes ( I will call them Data Model classes ) and bind them using Automapper.
3) Discuss how efficient and beneficial Automapper is than manual mapping.
However this first part will only consist of basic scenario. A basic mapping of Data Model classes to View Model which will be used by our views. The idea is to familiarize and know Automapper before we start unleashing all it’s powers.
Let’s start with Nuget. Nuget is a God send to me. I have had the pain of manually adding references, dll, scripts and css, setting dependencies to .Net project for a simple solution that is provided by a third party tool. Nuget makes all that as simple as few clicks. It’s a “Package Manager” that now ships with Visual studio 2010. You can add thousands of third party tool without all the hassle by searching in it’s console, It will automatically set references, dependencies and what not. You can learn more about Nuget here.
So I used Nuget to find Automapper. Let’s discuss a little bit about Automapper.
Automapper is a object to object mapper. You can potentially map any object to any other object easily via this Automapper library. I personally use to map my Data Model to View Model and vice versa.
Why? Because Automapper takes care of my unproductive coding where I just write redundant code of mapping View and Data Models, It automatically does it for me at fairly low cost. Yes! A few configurations and we are done! Just give Automapper your input model and gives you your desired output model. For complete details see this.
I like to use LINQ to query my SQL database in my MVC solution. So for testing purposes I created this database dragged tables to my LINQ file which automatically created Data Classes for me. These classes look fairly like my model but I don’t want to use them as my View Model ofcourse… So Let’s create a basic Customer Model (View Model). Here is how it looks.
Fairly simple. Fairly similar to my Data Model Class. For part 1 let’s keep it that way for now.
Now I have installed Automapper but haven’t done anything with it yet. Let’s do it.
I have created a Folder “Data Context” where I keep my .dbml file and I have created a static class called “Mapping“. Mapping because it’s going to perform mapping via Automapper and static because it will be common for all the sessions.
Here is how it looks.
There are three methods,
Customer_ViewModelToDataModel() -> It calls Mapper (Autmapper’s class) .CreateMap takes in two template types, since it’s View Model-> Data Model binding the first argument is Input(View Model) and second argument is desired output type which is DataContent.Customer our LINQ Customer class. Based on relationships in Database, LINQ created a Transcation member in Customer class which is not present in out View Model “Customer ” class hence we perform an “Ignore” to leave that member out of the mapping.
Thats it. Automapper created a map for us. We don’t even have to specify which members map to which in each models.. Cool isn’t it.
Similarly we do Data Model -> View Model, since View Model’s Customer class does not have a “Transaction” member there is nothing to ignore in it. We have created another map.
The third function PerformMapping just wraps these methods so we can call them together.
Now, the application needs to know about this mapping before anyone tries to map one object to another. Since this is Asp.net web project the best place to call our “PerformMapping” function will be Global.asax. Here is what I do there.
This is it. Your application knows that there is a map and these objects can be converted into one another via Automapper, but wait how to actually do that?
Here is how. I have created a view strongly typed with my View Model Customer. I will let MVC generate fields for me and this is what it gave me. Now we will perform simple insertion in DB for this posted View Model, we will convert this into Data Model Customer obect that LINQ recognizes and perform and insertion into a DB. So here are the snapshot for these steps
Notice I now use Mapper.Map instead of CreateMap, the templated parameters remain the same, the first one my input object, second one my output object but here i pass a object as a parameter so that Automapper can read from this object and write it to my desired object and give me back..
You would want to see that Model inserted don’t you.. Let’s generate another view called Show Customer which will fetch this view out, Only this time we will use Automapper to convert our Data Model LINQ Customer class to our View Model Customer class and pass that along in the View so that our view can display that. Here is a method that does that. Sure enough I have my Data Model as input, View Model as output and a LINQ queried data object of Customer passed in to Mapper.Map method. It gives me my View Model as expected. I now use this View Model and pass it down to my strongly typed View.
OK so we have seen what Nuget can do, and how via automapper we can convert the objects quickly into one another without writing any stupid redundant code, without even specifiying the individual member mapping in any of these model, pretty slick I think.
WAIT It is not over yet…
If you are anything like me you would wonder Automapper sure converts the data under the hood nicely but what are the cost that comes with it? Well for this kind of a mapping, not much.. Have a look a this.
Specially the last image.
I am comparing the binding of 1, 10, 100, 1000, 10000, 100000 set of sample models via manual mapping and Automapper, manual mapping ofcoruse is faster but Automapper is not left that far behind. But again this is my i7 with 8 Gb RAM server and you will hardly parse 100000 model on a single shot. Also It’s the application expected use which decide how crucial these timings are and whether it is wise to choose / add conversion layer between your data model and view model. That being said, do not forget this is a smile mapping and not fancy. In part 2 we will have complex model binding and again see if Automapper keeps up the performance like this..
Hope you will stay around…
Later..