16

What is the correct way to configure AutoMapper for global use.

I want to set it once and then used though out the app.

i have a strong feeling this is wrong. in fact i know this is wrong as this calls an new instance. I want a global config and then how do you call it. Can not find a good example!

this is what ive got: but its not what im wanting

public static class AutoMapperConfig
{
      public static IMapper GetMapper()
      {
          var config = new MapperConfiguration(cfg => {
              cfg.CreateMap<R_Logo, LogoDto>();
              //lots more maps...?
          });

          IMapper mapper = config.CreateMapper();
          return mapper;
      }
}

and then usage:

  var imapper = AutoMapperConfig.GetMapper();
  var dest = imapper.Map<R_Logo, LogoDto>(logo);

UPDATE based on: pinkfloydx33

Call this once and then the config is done.

public static class AutoMapperConfig
{
   public static void RegisterMappings()
   {
        AutoMapper.Mapper.Initialize(cfg => {
           cfg.CreateMap<R_Logo, LogoDto>();
            /* etc */
        });
    }
}
Seabizkit
  • 2,417
  • 2
  • 15
  • 32
  • 1
    It's recommended to use the instance version of the mapper which allows you to configure several instances, but there is still a static mapper. Just call `Mapper.Initialize` and then use the static `Mapper` property. https://github.com/AutoMapper/AutoMapper/wiki/Static-and-Instance-API – pinkfloydx33 Feb 28 '17 at 12:04

5 Answers5

17

Here is the steps to configure the automapper in asp.net core mvc.

1. Create the mapping profile class which extends from Profile

 public class ClientMappingProfile : Profile
 {
     public ClientMappingProfile ()
     {
         CreateMap<R_Logo, LogoDto>().ReverseMap();
     }
 }

2. Create the AutoMapper Configuration Class and add your mapping profile class here.

public class AutoMapperConfiguration
{
   public MapperConfiguration Configure()
   {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<ClientMappingProfile>();
        });
        return config;
    }
}

3. How we can use it.

       var config = new AutoMapperConfiguration().Configure();
       var iMapper = config.CreateMapper();

       var dest = iMapper.Map<R_Logo, LogoDto>(logo);
Ahmar
  • 3,717
  • 2
  • 24
  • 42
  • 1
    AutoMapper has built-in functionality to add profiles (see [Assembly Scanning for auto configuration](https://github.com/AutoMapper/AutoMapper/wiki/Configuration#assembly-scanning-for-auto-configuration)) – Alex Klaus Sep 08 '17 at 04:18
11

Set this in your StartupConfig or StartUp file.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
       // Web API configuration and services    
        .....

        MappingDTOModelToModel.Configure();
    }
}

Configuration of Mappings,

public static class MappingDTOModelToModel
{       
     private static void Configure()
     {
         Mapper.Initialize(cfg =>
         {
             cfg.CreateMap<R_Logo, LogoDto>()
                 .ForMember(x => x.ID,
                            m => m.MapFrom(a => a.ID))
                 .ForMember(x => x.FirstName,
                            m => m.MapFrom(a => a.FirstName)).ReverseMap();                    
         }
     }
 }

Calling it in a method,

public class MyService
{
    public void MyMethod(var model)
    {
        var myModel = Mapper.Map<LogoDto, R_Logo>(model);  
    }
}

Hope this helps,

Vivek Singh
  • 1,113
  • 10
  • 20
8

You can use the static mapper api as outlined here.

For example, somewhere in your application, probably during startup you would configure the static (global) mapper using something like:

AutoMapper.Mapper.Initialize(cfg => { 
   cfg.CreateMap<Type1, Type2>(); 
   /* etc */
});

Then, any time you need to use your "globally" configured mapper, you access it via the static Mapper property (which is an IMapper):

Type1 objectOfType1 = new Type1();
var result = AutoMapper.Mapper.Map<Type2>(objectOfType1);

You then have one mapper that has been configured for all the types/configurations/profiles you provide for the duration of your application without needing to configure individual mapper instances.

In short, you configure it once (perhaps at application startup). The static mapper instance (the IMapper) is then available anywhere throughout your application by accessing it via AutoMapper.Mapper.

Access via this static property is what you refer to as "globally" in your comments. Anywhere you need it just use AutoMapper.Mapper.Map(...) So long as you've called Initialize once first.

Note that if you call Initialize more than once on the static instance, each subsequent call overwrites the existing configuration.

WARNING In a previous release of AutoMapper, the static mapper was removed. It was later added back in and I don't know if they guarantee that it will remain in future versions. The recommendation is to use your own configured instances of a mapper. You can store it in a static property somewhere if you need it. Otherwise you can look into profiles, etc for easy ways to configure your mapper so that having your own instance isn't necessarily a "hassle".

pinkfloydx33
  • 11,863
  • 3
  • 46
  • 63
  • how is this used globally i have read the docs... cant see how to implement globally... ie how is this called across the app. – Seabizkit Feb 28 '17 at 12:17
  • It's a static instance. Once it's configured once in your app (at startup perhaps) you call `AutoMapper. Mapper` which is an instance of IMapper. You make calls to it anywhere once you've configured it as its been "globally" initialized – pinkfloydx33 Feb 28 '17 at 12:19
  • please check what I've done in the Update to the Question. Would of been nice to link the instance and the config, i.e. i use this in a service class, as my service classes don't have a starting point(app start or Global.asax), i would need to call configure in each service class... – Seabizkit Feb 28 '17 at 12:34
  • No need to update your question since you've accepted an answer. If you have a new question then you shoukd ask it – pinkfloydx33 Feb 28 '17 at 12:35
  • i get ya, but was looking for example of the above, rather trying to interpret what someone means. IE to your WARNING it would be nice to have an implementation of that so i can see what would be a better implementation. IE and Example of what a configure instance of this would look like. – Seabizkit Feb 28 '17 at 12:40
1

Our solution to this problem was to first create a selection of attributes that can decorate a class as being "Mappable" (either To, From or Both). Then you can initialize the AutoMapper in a single location, usually post application initialization and use Reflection to dynamically create a map for each instance of the decorated classes.

Here's an example:

var types = _myTypeFinder.Find(type =>
    type.IsDefined(typeof(AutoMapperAttribute)) ||
    type.IsDefined(typeof(AutoMapperFromAttribute)) ||
    type.IsDefined(typeof(AutoMapperToAttribute))
    );

Mapper.Initialize(cfg =>
{
    foreach (var type in types)
    {
        AutoMapperHelper.CreateMap(type, cfg);
    }
});
Kallum Tanton
  • 802
  • 7
  • 22
1

I have find best solution for configuration auto mapper in .Net Core. Multiple Profile. Just use this:

services.AddSingleton(provider => new MapperConfiguration(cfg =>
    {
        cfg.AddProfile(new sampleProfileMapper());
    }).CreateMapper());
Cristik
  • 30,989
  • 25
  • 91
  • 127