Object-object mapping

By eidias on (tags: automapper, categories: code)

I recently stumbled upon automapper. It’s a handy little library used for object-object mapping. Let’s take a look at that.

The simplest usage

If you find yourself having classes such as Foo, FooViewModel, FooListViewModel, FooDTO you probably have a decent amount of code which looks more or less like this:

   1: var foo = GetFoo();
   2: var fooViewModel = new FooViewModel
   3:     {
   4:         Prop1 = foo.Prop1,
   5:         Prop2 = foo.Prop2,
   6:         Prop3 = foo.Prop3,
   7:         Prop4 = foo.Prop1 + foo.Prop2
   8:     }

If you’re lazy like me, you probably wrapped that in some extension methods, class methods or created a bunch of converters.

This is exactly the type of code you do not need to write if you’re using automapper. It’s purpose is to help you with ‘converting’ one object into another. It’s mostly convention based (though also allows explicit member mapping) and very easy to use. Here’s a quick example:

   1: Mapper.CreateMap<Foo, FooDto>();
   3: Foo foo = GetFoo();
   4: FooDto dto = Mapper.Map<Foo, FooDto>(foo);

Note that you need to call the CreateMap function only once – so at application start.

Automapper also has a couple of nice features including flattening, support for lists and nested types. You can read all about it here. The docs are short and concise. It’s available on NuGet so getting started with it is painless.

I encourage you to try it.

What else could it be used for?

As I was playing around with it, I thought that maybe it could be used for something more (or to be clearer – for some higher level things).

As I’m an mvc guy the first thing that came to my mind was model binding. Imagine that you have an action that operates purely on domain models, but the views (in most cases) will require it’s view models.

Now the simplest thing to do is to use automapper and just pass the mapped object as view data – that’s not even a full line of code, but what if I could pass the domain object as view data, and get the mapped view model at the other end?. As I started to explore this a bit further, I found out that MVC kind of does that already. Default model binders work on property level, they don’t match the type itself but the properties that it has. So if you have a view that has FooViewModel as it’s model and you send post data to an action that accepts Foo as it’s argument, then all the properties that have the same name will be populated. This is as ‘basic’ as it gets – if automaper was to be used here, we could benefit from it’s set of more elaborate features – not just value reassignment for properties with the same name.

The thing is that this only works one way, which means, that if you try to display a view that accepts FooViewModel and you pass in Foo as the data to it, you’ll get an exception – which is understandable.

But what do you know, Jimy Bogard (the creator of automapper) has already thought of that and you can read about it in his post.

Anything else?

Sure, what about LINQ? How many times did you write this:

   1: var fooPart = Foos.FirstOrDefault().Select(f => new FooPart{Prop1 = f.Prop1, Prop2 = f.Prop2});

or something similar? With automapper you can now write this:

   1: var fooPart = Foos.Project().To<FooPart>().FirstOrDefault();

looks nice to me. No docs on this yet, but you can look at the blog post for some insight.