How to add a mapping in AutoMapper after calling Initialize?

I have several ASP.Net applications that share the mapping code, so I created a generic init automapper class.

However, in one of my applications, I have some specific classes that I want to add to the configuration.

I have the following code:

public class AutoMapperMappings { public static void Init() { AutoMapper.Mapper.Initialize(cfg => { ... A whole bunch of mappings here ... } } } 

and

 // Call into the global mapping class AutoMapperMappings.Init(); // This erases everything AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<CustomerModel, CustomerInfoModel>()); 

How to add this unique mapping without destroying an already initialized one?

+7
source share
5 answers

A quick example that allows you to initialize AutoMapper 5.x several times ... Well, this is not very nice;)

 public static class MapperInitializer { /// <summary> /// Initialize mapper /// </summary> public static void Init() { // Static mapper Mapper.Initialize(Configuration); // ...Or instance mapper var mapperConfiguration = new MapperConfiguration(Configuration); var mapper = mapperConfiguration.CreateMapper(); // ... } /// <summary> /// Mapper configuration /// </summary> public static MapperConfigurationExpression Configuration { get; } = new MapperConfigurationExpression(); } // First config MapperInitializer.Configuration.CreateMap(...); MapperInitializer.Init(); // or not //... MapperInitializer.Configuration.CreateMap(...); MapperInitializer.Init(); 

The idea is to store an instance of MapperConfigurationExpression instead of an instance of MapperConfiguration.

+9
source

This should be possible if you are using the instance API that AutoMapper provides instead of the static API. This wiki page details the differences between the two.

Essentially, instead of calling AutoMapper.Mapper.Initialize(cfg => ...) again for your additional mapping, which overwrites the entire global mapping configuration with this single mapping, you need to create another mapper object with the instance API using:

 var config = new MapperConfiguration(cfg => cfg.CreateMap<CustomerModel, CustomerInfoModel>() ); var mapper = config.CreateMapper(); 

Of course, to use this new cartographer, you will need to do something like var mappedModel = mapper.Map<CustomerInfoModel>(new CustomerModel()); specifically when matching objects using your optional matching configuration. How practical this is in your case, I do not know, but I believe that this is the only way to do what you need.

+2
source

You cannot, but instead of initializing mappings from your Init method, you can force it to return a function that can be called inside a call to Mapper.Initialize ().

So your Init method looks like this:

 public static Action<IMapperConfigurationExpression> Init() { return (cfg) => { ... A whole bunch of mappings here ... }; } 

Then from your application, where you want to get additional mappings:

 var mappingsFunc = MyClass.Init(); Mapper.Initialize((cfg) => { mappingsFunc(cfg); ... Extra mappings here ... }); 

or you can reduce it a little ...

 Mapper.Initialize((cfg) => { MyClass.Init()(cfg); ... Extra mappings here ... }); 

Hope this helps.

+1
source

Automapper 5+

I have an initialization class in my main assembly

  public static class Mapping { public static void Initialize() { // Or marker types for assemblies: Mapper.Initialize(cfg => cfg.AddProfiles(new[] { typeof(MapperFromImportedAssemblyA), typeof(MapperFromImportedAssemblyB), typeof(MapperFromImportedAssemblyC) }) ); } } 

Then in every assembly that requires a mapper

 public class MapperFromImportedAssemblyA : Profile { public MapperFromImportedAssemblyA() { // Use CreateMap here (Profile methods are the same as configuration methods) } } 
0
source

This is what I hacked for my requirement.

Actual Configurator

 public static void Configure(params Action<MapperConfigurationExpression>[] registerCallbacks) { MapperConfigurationExpression configuration = new MapperConfigurationExpression(); foreach (Action<MapperConfigurationExpression> regCallBack in registerCallbacks) { regCallBack.Invoke(configuration); } AutoMapper.Mapper.Initialize(configuration); } 

Cartographic Group 1

 public class AutoMapperConfigSet1 { public static void RegisterTypes(MapperConfigurationExpression configuration) { configuration.CreateMap<Foo, Bar>(); } } 

Cartographic Group 2

 public class AutoMapperConfigSet2 { public static void RegisterTypes(MapperConfigurationExpression configuration) { configuration.CreateMap<Foo1, Bar1>(); } } 

Upon initialization

 Configure(AutoMapperConfigSet1.RegisterTypes,AutoMapperConfigSet2.RegisterTypes); 
0
source

All Articles