Finding Shortcuts With AutoMapper

I may or may not have mentioned AutoMapper in my previous posts, but since Version 1.0 came out today I figured I should cover it.

AutoMapper is a open-source project hosted on CodePlex that the web team has used for the last few projects. Basically, it “auto-maps” from one object to another, which by itself doesn’t sound too complicated, but it does give a bunch of advanced options for dealing with complex types, value translation, and other complex scenarios. But why would we need it? Really, it’s just a matter of convenience and cleaner code. For example, let’s say we’re creating a collection of Data Transport Objects from a strongly-typed DataTable we just got back from the DB.

List<EmployeeTransport> employees = new List<EmployeeTransport>();
Foreach(EmployeeDataRow row in employeesTable)
    EmployeeTransport transport = new EmployeeTransport();
    transport.EmployeeID = row.EmployeeID;
    transport.EmployeeName = row.EmployeeName;
    transport.PhoneNumber = row.PhoneNumber;
    transport.Address1 = row.Address1;
    transport.City = row.City;
    transport.StateProv = row.StateProv;
    //etc, etc, etc
return employees.ToArray();

I’m sure you’ve all seen that code before. Now, let’s refactor with AutoMapper:

return AutoMapper.MapObject<EmployeeDataRow[], EmployeeTransport[]>(employeeTable.Rows);

Seems a bit cleaner. Actually, the MapObject method is a static method we created to do a lot of the manual work that AutoMapper requires. How AutoMapper works, it uses reflection to iterate over each property in the “source” object, and tries to find a matching property in the “destination” object. It does this by comparing both property name and data type, which works perfectly fine for any of the data types built into .NET. Where it gets a bit tricky is when you have object properties in either the source or destination – because it doesn’t really “know” about those types, you have to set up manual mappings for them. Luckily we were able to whip up a utility function that both creates the mapping and returns the translated objects for you.

Other more advanced scenarios exist when you want one or more properties to be translated to a different or composite value on the target object, for instance changing “US” to “United States” or Area Code = “306” and Phone Number = “123-4567” to “306-123-4567”. The same idea applies however, where you setup a mapping “rule” once for a combination of source and destination object types, and then you can call MapObject as much as you want without having to re-code anything.

Keep in mind this isn’t exactly a full-fledged “object relational mapper”, the mappings performed by AutoMapper are one-way only and really only meant for cross-domain translations (web service to client app, database to domain, etc.). You could potentially write two seperate mappings to handle that (database –> DTO, and DTO –> database) but at that point it’s probably a better idea to just look at using an ORM.