2

I have AutoMapper mappings, which look like this:

Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<Person, PersonViewModel>();
        cfg.CreateMap<Order, OrderViewModel>();
    });

I am trying to figure out where to put this code in an MVC application. There are two options:

1) Composition Root

public class CompositionRoot : IWindsorInstaller
    {
      //Castle Windosr configuration goes here
      //Call to AutoMapper configuration class here
    }

2) Global.asax

Questions like this suggest it: Where to place AutoMapper.CreateMaps?

My gut is telling me to put it in the Composition Root, however everywhere I read tells me to put it in the Global.asax.

Waleed Iqbal
  • 1,308
  • 19
  • 35
w0051977
  • 15,099
  • 32
  • 152
  • 329

2 Answers2

3

If you take a look in Global.asax at Application_Start. You can already see things like RouteConfig.RegisterRoutes etc. These typically call static methods on classes in the App_Start folder. I usually add a class called AutoMapperConfig with a static method called Configure. I then add this to the list in Gloabl.asax. See below:

void Application_Start(object sender, EventArgs e)
{
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    ModelBindersConfig.Configure();
    DevExpressConfig.Configure();
    AutoMapperConfig.Configure();          
}
Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47
renz
  • 165
  • 3
  • 12
1

In the past I have registered them as part of a static call from Global.asax. However, the static Mapper.Map methods are being deprecated so I've recently created a static class to setup the configuration mappings. I then call this within the composition root of my application to register the IMapper object that I can then take as a dependency in any classes.

E.g.

public static class AutoMapperConfig
{
  public static MapperConfiguration ConfigureMapping()
  {
    return new MapperConfiguration(cfg =>
    {
      cfg.CreateMap<Person, PersonViewModel>();
      cfg.CreateMap<Order, OrderViewModel>();
    });
  }
}

Using Castle Windsor you could do something like:

container.Register(
  Component.For<IMapper>()
    .UsingFactoryMethod(() => AutoMapperConfig.ConfigureMapping().CreateMapper())
    .LifeStyle.Singleton);
Fermin
  • 34,961
  • 21
  • 83
  • 129
  • I don't believe that AutoMapperConfig class will compile. Should it contain a method? – w0051977 Jan 25 '18 at 14:07
  • Can I ask why you use the Composition Root instead of the Global.asax like the other answerer? Thanks. – w0051977 Jan 25 '18 at 20:11
  • As mentioned at the start of the answer it is so that I can register the `IMapper` class in the DI container. This removes the dependency on static Mapper.Map calls (which is being made obsolete in Automapper 5), making testing etc easier. – Fermin Jan 26 '18 at 00:50