An AutoMapper success story


I got a cool message on the AutoMapper mailing list from Howard Van Rooijen on how they used AutoMapper in a site they recently launched to production:

Hello AutoMapper Community,

I just wanted to let you know that an e-commerce site which uses AutoMapper as part of it’s core architecture has just been released into the wild:

http://www.fancydressoutfitters.co.uk

And I wanted to say a HUGE thank-you to Jimmy & the Community for this wonderful tool – that helps remove so much commodity plumbing code from the solution.

We were a little sceptical at the start of the project that AutoMapper would “cut the mustard” when it came to the performance requirements of a public facing, high load, e-commerce site because of the amount of reflection AutoMapper uses at its core, but we have been incredibly impressed with the performance of the solution under load.

The site is based on the S#arp Architecture Framework and its become very apparent how well AutoMapper fits into MVC style architecture as it enables easy separation of concerns with regards to object conversion (entities & ViewModels). Once we moved from hand-cranked converters to AutoMapper it was amazing how much cleaner our code became – so much so that we modified the overall solution architecture to incorporate explicit mapping layers (see attached image). Our general pattern of usage within MVC is as follows:

  1. Map input into Domain Entities in the Controller

  2. Pass Domain Entities into Task Layer to “do stuff”

  3. Map output of Task Layer (Domain Entities) into ViewModel

  4. Pass ViewModel to ViewEngine

Simple, slick and clean.

To formalise the Mapping Layer and make it testable we implemented a simple interface:

public interface IMapper<TInput, TOutput>

{

TOutput MapFrom(TInput input);

}

Next we’d implement a custom marker interface so that we could resolve the mapper from the DI container and we adopted the naming convention Mapper:

public interface IEditModelEntityMapper : IMapper<EditModel, Entity>

{

}

Then finally implement the interface:

public class EditModelEntityMapper : IEditModelEntityMapper

{

public EditModelEntityMapper()

{

Mapper.CreateMap<EditModel, Entity>()

.ForMember(x => x.Property, y => y.MapFrom(z => z.Property));

}

public Entity MapFrom(EditModel input)

{

return Mapper.Map<EditModel, Entity>(input);

}

}

Then to actually use it in the MVC app:

public class CustomController : Controller

{

private readonly ITasks tasks;

private readonly IEditModelEntityMapper editModelEntityMapper;

private readonly IOutputViewModelMapper outputViewModelMapper;

public CustomController(ITasks tasks,

                                           IEditModelEntityMapper editModelEntityMapper,

                                           IOutputViewModelMapper outputViewModelMapper)

{

this.tasks = tasks;

this.editModelEntityMapper = editModelEntityMapper;

this.outputViewModelMapper = outputViewModelMapper;

}

public ActionResult Index(EditEntity input)

{

var entity = this.editModelEntityMapper.MapFrom(input);

                var output = this.tasks.DoSomething(entity)

                var viewModel = this.outputViewModelMapper.MapFrom(output);

return View(viewModel);

}

}

For those who are interested – here’s a little more info:

– We ran the project using Scrum and delivered in 20 weeks: 10 x 2 week iterations

– It’s based on the S#arp Architecture framework, which we extended to support, AutoMapper, Spark and ViewModels
– Solution performs very well: 1000 concurrent users per web server, generating around 180 pages per second across 2x single quad core 64bit servers.

Again, many thanks,

Howard

Howard also shared a neat little diagram of his architecture:

image

This is one of the greatest feelings from doing OSS – that something you created basically just for yourself can also help out other folks out there trying to deliver value for their customers.  Thanks for all the feedback everyone, as well as kudos to the S#arp Architecture team for building such a great framework for MVC.

Bugs, defects and feedback