Aleksander Bethke
Aleksander Bethke

Reputation: 1479

Injecting AutoMapper instance

I have an ASP.NET MVC application with all mappings registered during the bootstrap in this way:

Mapper.CreateMap<AdvicesModel, Advices>();

So far we've used it the "old" way statically:

Mapper.Map<Advice>(adviceDto)

So far so good.

After the update to version 4 of AutoMapper I've seen that it is recommended to use it constructing an Instance. Can someone point me how to properly instruct Castle to Inject an instance of AutoMapper to my dependencies and user it not statically.

What I imagine is something like this:

var viewModel = mapper.Map<CartViewModel>(cart);

with IMapper instance injected.

Upvotes: 4

Views: 6926

Answers (2)

Rex
Rex

Reputation: 678

For the native ASP.net 5 DI:

  1. create a new class extending AutoMapper.Profile, with a single overrided Configure, create all the maps in the Configure.
public class YourProfile : Profile
{
   protected override void Configure(){
       //CreateMap<T, TDto>().ForMember....   
   }
}
  1. in startup.cs, setup the DI like this:
 public void ConfigureServices(IServiceCollection services)
 {
  //...
   var config = new MapperConfiguration(cfg =>
   {
     cfg.AddProfile(new YourProfile());
   });
   services.AddSingleton<IMapper>(sp => config.CreateMapper())
  //...
 }
  1. Now injection:
public class Repository{
    private readonly IMapper _mapper;
    public Repository(IMapper mapper){
        _mapper = mapper;
    }
    public List<TDto> ToDtoList<TDto>(){
     return _mapper.Map<List<TDto>>(sourceList);
    }
 }

Source: https://pintoservice.wordpress.com/2016/01/31/dependency-injection-for-automapper-4-2-in-asp-net-vnext-mvc-project/

Upvotes: 6

Ian Barrett
Ian Barrett

Reputation: 116

I don't think services.AddSingleton<> is Castle Windsor so below is my CastleWindsor installer.

        private static void RegisterProfilesAndResolvers(IWindsorContainer container)
    {
        // register value resolvers
        container.Register(Types.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IValueResolver>());

        // register profiles
        container.Register(Types.FromThisAssembly().BasedOn<Profile>().WithServiceBase().Configure(c => c.Named(c.Implementation.FullName)).LifestyleTransient());

        var profiles = container.ResolveAll<Profile>();

        var config = new MapperConfiguration(cfg =>
        {
            foreach (var profile in profiles)
            {
                cfg.AddProfile(profile);
            }
        });

        container.Register(Component.For<MapperConfiguration>()
            .UsingFactoryMethod(() => config));

        container.Register(
            Component.For<IMapper>().UsingFactoryMethod(ctx => ctx.Resolve<MapperConfiguration>().CreateMapper(ctx.Resolve)));
    }

I'm not sure if this is ideal/optimal etc but it does seem to work :-)

Upvotes: 7

Related Questions