Upgrading AutoMapper


Thursday 26 Jan 2017 at 21:00
Development  |  c# automapper upgrade

On more than one or two occasions now, I've found myself working with a codebase that uses AutoMapper to perform mapping between objects, most commonly to map data entity objects to their equivalent domain objects.

These codebases often are using a version of AutoMapper prior to version 4.2 which is the version that AutoMapper decided to remove it's static API. I often find the need to upgrade the version of AutoMapper that's in use for any one of a number of different reasons and so I find myself having to re-write all of the AutoMapper initialisation code as the old way of creating mappings is no longer supported.

The problem here is that, in a large enough codebase, moving from purely static mappings as was done with AutoMapper prior to v4.2 to non-static mappings that would need to be either manually constructed or injected into all of the places in the codebase that would require them.  This is often a non-trivial feat and makes moving from static mappings to non-static mappings a much larger job that you might ideally like it to be.

The "proper" way to configure your AutoMaper mappings these days is write code similar to this:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<SourceObject, DestinationObject>();
});

and then to pass that config object around, or inject it into the class that might need your mapping config.  Of course, if that class is short-lived, you'll need to re-create these mapping configs again and again.  Whilst this is undoubtedly the "best" approach and does not require any static objects, it's sometimes not immediately feasible in an a large, legacy codebase.

There is, however, a way of changing your old, static API-based, mapping configurations in such a way that they continue to use a static object - albeit not the same one as was in AutoMapper < v4.2 - such that the change can be a "drop-in" replacement without having a knock-on ripple effect through out the rest of the codebase.

The Old Way

So the old way of configuring AutoMapper mappings with the static API was something very similar to this:

public class AutomapperConfig
{
    public static void Configure()
    {
        Mapper.CreateMap<SourceObjectA, DestinationObjectA>();
        Mapper.CreateMap<SourceObjectB, DestinationObjectB>();
        Mapper.CreateMap<SourceObjectC, DestinationObjectC>();
    }
}

and the static Configure method would be called within some entry point of your program (i.e. inside the Application_Start method of the Global.asax.cs class)

The New Way

And here's the new way of performing the same thing.  A slight syntactical change to the code and it's a "drop-in" replacement.

public class AutomapperConfig
{
    public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SourceObjectA, DestinationObjectA>();
            cfg.CreateMap<SourceObjectB, DestinationObjectB>();
            cfg.CreateMap<SourceObjectC, DestinationObjectC>();
        }
    }
}

Note how we use the new Initialize method of the static Mapper object passing in a lambda that performs our mapping configurations rather than constructing a new instance of the MapperConfiguration object to pass to the relevant part of our code that needs to perform mappings.

And with that, we can easily upgrade from AutoMapper pre-v4.2 to a version post-v4.2 without the code changes being too onerous.