I have a pattern which has served me well on several past projects. I use concrete mapper classes that use AutoMapper internally as an implementation detail. This lets me get back a few things I enjoy, such as being able to easily find usages of a particular mapping. For instance, a FooMapper class will create Foo objects from a variety of different sources.
public class FooMapper : EntityMapper<Foo>, IFooMapper
{
static FooMapper()
{
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<Bar, Foo>();
cfg.CreateMap<Baz, Foo>();
});
}
public Foo Map(Bar source)
{
return AutoMapper.Mapper.Map(source, new Foo());
}
public Foo Map(Baz source)
{
return AutoMapper.Mapper.Map(source, new Foo());
}
}
In the real world, there's usually more to it than that, with the base EntityMapper knowing how to handle the simple Foo to Foo mapping for unproxying things, and with each individual Map method doing any custom code-based work as appropriate. In some cases, certain mappings don't even use AutoMapper. One of the big wins, though, is that I can find usages of the individual mappings quite easily, and the rest of the code doesn't even need to know that AutoMapper is involved. I don't necessarily like my choice of tools leaking into the rest of my code base. I also favor thin repository layers to abstract which ORM I'm using, by the way.
I want to move to AutoMapper 5, and modernize the pattern, but I need to retain the ability to update the mappings from the static constructors of the concrete mapper classes. What I'd really like to do is hold the configuration in the base class as a static so that all of MY mappings end up together in that one configuration together, and can leverage each other, but wouldn't see mappers defined in other "trees", with EntityMappers not knowing about ViewModelMappers, etc.
My current problem is that AM5 really wants a separate configuration step before you start actually using the mappers. My old method relied on the mappers lazily adding themselves to the mix the first time they are used in any given run. If a particular mapper is never used in a run, then it will never have configured itself to begin with. I could add methods to each mapper that take in the configuration expression and configure themselves, but I would lose this passive configuration, and have to maintain a master list of mappings by hand, updating it whenever I add a new type of mapping to the project.
Is there any compromise in AM5, or should I just keep using the resurrected static API? Am I losing out on AM5's new performance gains if I stick with the static API?