Is it possible to use methods with new MapperConfiguration?

2.6k Views Asked by At

I got a very simple question... Is it possible to setup a AutoMapper like this:

public IMapper Init()
{
     var config = new MapperConfiguration(cfg =>
     {
         cfg = MappingModelsToViewModels(cfg);
      });

      return config.CreateMapper();
}

I splitted each mapping in to method like this:

 public IMapperConfigurationExpression MappingModelsToViewModels(IMapperConfigurationExpression cfg)
 {
     cfg = SKU(cfg);
     cfg = Lot(cfg);
     cfg = SalesRate(cfg);
     cfg = SpecialSalesRate(cfg);
     cfg = Order(cfg);
     //...

     return cfg;
}

        public IMapperConfigurationExpression SKU(IMapperConfigurationExpression cfg)
        {
               // HTTPGET
               cfg.CreateMap<SKU, SKUViewModel>() //...
               return cfg; 
        }

I ask because I got this error:

Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.

And I did a test by moving a part of the mapping code in to the new MapperConfiguration and it was working.

Thanks,

David

2

There are 2 best solutions below

0
On

I usually accomplish this by using the profile option automapper has. If gives both flexibility and less places to modify later on-

The Profile definition, done by deriving from AutoMapper Profile class-

public class Profile1 : Profile 
{
    public Profile1(){ //... for version < 5, use protected void Configure
         CreateMap<SKU, SKUModel>()
         //........
    }
}

Then initialise automapper and load profiles -

MapperConfiguration = new MapperConfiguration(cfg =>
{
    cfg.AddProfile<Profile1>();
});
Mapper = MapperConfiguration.CreateMapper();

Or you can let AutoMapper detect the profiles by itself -

// Assembly objects
Mapper.Initialize(cfg => cfg.AddProfiles(/*.... supply the assembly here ...*/));

more can be found here -

https://github.com/AutoMapper/AutoMapper/wiki/Configuration#profile-instances

0
On

There are lot of ways to configure AutoMapper. I personally like the following approach -

Global.ascx.cs

protected void Application_Start()
{   
    ...
    AutoMapperConfiguration.Initialize();
    ...
}

AutoMapperConfiguration.cs

public static class AutoMapperConfiguration
{
    public static void Initialize()
    {
        MapperConfiguration = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<SKU, SKUViewModel>();
            cfg.CreateMap<SKUViewModel, SKU>();

            cfg.CreateMap<Lot, LotViewModel>();
            cfg.CreateMap<LotViewModel, Lot>();
        });
        Mapper = MapperConfiguration.CreateMapper();
    }

    public static IMapper Mapper { get; private set; }

    public static MapperConfiguration MapperConfiguration { get; private set; }
}

Usage

Usage will be like -

SKUViewModel model = AutoMapperConfiguration.Mapper.Map<SKU, SKUViewModel>(sku);

Unit Test

[Test]
public void AutoMapperConfigurationInitializeValid()
{
   AutoMapperConfiguration.Initialize();
   AutoMapperConfiguration.MapperConfiguration.AssertConfigurationIsValid();
}