Using AutoMapper with Attributes
Spencer Schneidenbach
—December 18, 2015
UPDATE: don't do this. If you really want to use attributes with maps (I don't recommend it, personally) use the latest version of AutoMapper, which has attribute support built in: https://docs.automapper.org/en/stable/Attribute-mapping.html
AutoMapper is awesome. For those of you who don’t know what it is, it’s this lovely little .NET library that allows you to easily map one type to another. It sucks to write code where all you’re doing is setting properties from one object to another, like this:
Customer customer = GetCustomer();
Address address = new Address();
address.Address1 = customer.Address1;
address.Address2 = customer.Address2;
//...and so on...
Repeat for 10 more properties and you have yourself 13 lines of code, just to create a new object out of another. Ugh! However, there’s always hope. With AutoMapper, that nonsense becomes:
Customer customer = GetCustomer();
Mapper.CreateMap<Customer, Address>(); //this sets up the mapping between the two objects
var address = Mapper.Map<Address>(customer); //this creates the Address object
And that’s it. 14 lines of code to 3 for the exact same result. AutoMapper is so great.
However, being the software geek that I am, I wanted to take things a bit farther. I use a lot of separate classes for API/view models in my ASP.NET work (using the highly recommended model factory pattern, with the factory being AutoMapper :), and I’ve at least once ended up with a single static method that calls Mapper.CreateMap()
100 or more times. It was kinda ugly, plus sometimes I’d add a new view model class and forget to call CreateMap to map it to its “parent” object, which caused an exception at runtime when I tried to create the mapping. (Calling Mapper.Map()
before calling Mapper.CreateMap()
on those objects’ types results in an exception.)
Finally, I wanted my code to be a little more self-documenting, and adding attributes that define a mapping helps myself and others remember exactly what a view model is for.
I like this way better:
[MapFrom(typeof(Customer))]
public class Address { ... }
static void Main()
{
typeof(Address).Assembly.MapTypes();
}
To that end, I’ve written and released my first NuGet library, AutoMapper.Attributes. The code is open source – you can find it on GitHub. It allows you to add attributes to classes to define your mappings. You can also use attributes to map properties to one another. The property attributes support dot notation, so you can map a deeply nested source property to a destination property with ease.
I’ve added all of the documentation you’ll need, including code samples, to the README on GitHub. Please enjoy and hit me up with any feedback you have!