AutoMapper IOC vs. Static

AutoMapper is useful tool. Saves serious time in the mapping of object properties between different classes. Objects are mapped when moving between layers of your application. This helps to maintain clean separation between the layers.

Like any other framework that has been around for a while it's undergone some changes. For several years AutoMapper shipped with a static API. Jimmy Bogard (creator of AutoMapper) has a few posts on his blog that gives the details.

AutoMapper and IOC

More recently the static API has been removed from AutoMapper.

Removing the static API from AutoMapper

In our codebase we moved to the newer version of AutoMapper with the IoC friendly API. It brought a few issues to the light.

Where does the Map Function live? The obvious answer is you would have a line either a controller or a command. In this case moving from the static API to a mapping service isn't a huge leap. It only requires injecting a mapper instance.

// Maps from Domain Object to DTO
//Static
OrderDto dto = Mapper.Map<Order, OrderDto>(order);
 //Static
OrderDto dto = _mapper.Map<Order, OrderDto>(order);

Backing up a little, how would you do the mapping without AutoMapper? A simple map function would do the trick.

public static OrderDto Map(Order obj) {
    '''... // all the mapping
    return oderDto;
}

That map function only requires the objects being mapped. No external dependencies. It's pass through code for unit tests. That function can live almost anywhere in the code base. Though I'd argue there are more and less correct places you'd expect to find it.

In our codebase I developed a pattern with generics to handle add and update of data for CRUD functions. Two interfaces define the mappings for add and update. IMapTo used for add and IMapOnto used for updates. If a model implements either or both of these interfaces I can wire up a generic command that does all the hard work. Code reuse at its best.

IoC in my Models No thanks. While the static interface made this plausible. The IoC interface makes this a little painful. The mapper instance could be passed into the model function via parameter injection. That felt messy and required injection into the top level. I've created a static factory that returns my mapping instance.

 public Order MapOnTo(Order state) {
     var mapper = new    MapperFactory().CreateMapper<OrderMappingProfile>();
     return mapper.Map(this, state);
}

For now this works fine, but serves as an example of why the static mapper had its place in the API. RIP static mapper :(

Other Options It is also worth mentioning that there are other mapping frameworks that you might want to look at. The most interesting that I've seen to date is Mapster