I have been using AutoMapper for a few projects lately and just love its power and ease of use. My projects have become not only simpler to manage, but easier to do the right thing. What I mean by right thing, is creating ViewModels and Domain objects in my ASP.NET MVC projects. Although it seems like extra work to create multiple classes that seem to do what seems like the same thing, down the road it is a much better way to do things because of maintainability of views and domain logic not interfering. I am not going to get into the reason you would do this, but you can find out more here. Jimmy Bogard has a great article here as to why ViewModels are so important.
Sometimes when you do not want to have to create your maps ahead of time, it can be useful to use an extension method on IEnumerable which will work with IQueryable and any other Interface that implements IEnumerable .
An example is to map a complex query to a complex domain model. For instance, lets say I want to do a complicated db query using linq:
var q = from c in db.Customers select new { c.CompanyName, c.ContactName, Orders = (from order in db.Orders where order.CustomerID == c.CustomerID select order) }; AutoMapperHelper.TryCreateMap<Order, MyOrder>(); var a = q.ToModelList<ComplexCustomer>();
And here is the ComplexCustomer class that AutoMapper maps to:
public class ComplexCustomer { public string CompanyName { get; set; } public string ContactName { get; set; } public List<MyOrder> Orders { get; set; } }
Notice the extension Method: ToModelList(). This will execute the query to a list then automap it dynamically to the anonymous type or a defined type.
Here are the extension methods:
public static IList<TDestination> ToModelList<TDestination>(this IEnumerable query) { var output = new List<TDestination>(); var sourceType = query.GetType().GetGenericArguments()[0]; var destType = output.GetType().GetGenericArguments()[0]; foreach (var src in query) { var mySrc = Mapper.DynamicMap(src, sourceType, destType); output.Add(Mapper.DynamicMap<TDestination>(mySrc)); } return output; }
There are two ways to use this extension, one is to tell the extension both the source and destination generic classes or just pass in the destination and it will use dynamic mapping to figure out what the source is. Notice that there also is a AutoMapperHelper class which helps to find out if the map you want is already in memory since AutoMapper stores the maps statically. We found that by not doing this it created a performance issue.
All in all, we are loving AutoMapper and I hope that others find this extension very useful. I have already used it with SubSonic 3, EF 4 and Action Filter Atrributes in an ASP.NET MVC Project.
Remember Me
a@href@title, b, blockquote@cite, i, strong, u
Powered by: newtelligence dasBlog 1.9.6264.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
E-mail