Autofac 3 and Automapper

断了今生、忘了曾经 提交于 2019-12-05 02:03:37

问题


Does anyone know of a comprehensive guide to setting up Automapper with Autofac. I'm new to both but I have played around with the static Mapper class however I want to be able to mock and inject IMappingEngine and create a configuration that sets up all my mappings. All the guides I have looked at so far don't really explain what is going on and I can't quite work it out. Also I am using Autofac 3.0 which seems to have some differences in the ContainerBuilder methods which doesn't help (the reason I'm using it is that Autofac.mvc4 depends on it).

Update:

OK, the simplest solution seems to work well enough, however I had not seen it anywhere on the internet and that maybe for a good reason that I don't know? The simplest thing to do is just to Register the static Mapper.Engine as IMappingEngine and still use the static Mapper.CreateMap to configure in the first place.

var builder = new ContainerBuilder();
builder.Register<IMappingEngine>(c => Mapper.Engine);

Now Autofac can inject the IMappingEngine into your constructors. This does mean that Mapper will handle the IMappingEngine singleton rather than Autofac and Autofac is just acting as a wrapper for it. I would like Autofac to handle the IMappingEngine instance but I'm not sure how?


回答1:


Your simple solution is OK provided that you don't want to mock the mapper in unit tests or create mappers with modified configurations for nested lifetime scopes (the latter one looks a bit weird to me, but who knows).

If you need that, you can pick up some pieces of code from the Mapper class and register components like this:

builder.Register(ctx => new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers()))
       .AsImplementedInterfaces()
       .SingleInstance();

builder.RegisterType<MappingEngine>()
       .As<IMappingEngine>();

I'm not sure if you really need to make IMappingEngine a singleton. It should be quite lightweight to create per dependency.

Now you can use it like this:

// in a bootstrapper:
var mapperConfig = ctx.Resolve<IConfiguration>();
mapperConfig.CreateMap<A, B>();

// later on:
public class X{
    IMappingEngine _mapper;

    public X(IMappingEngine mapper){
        _mapper = mapper;
    }

    public B DoSmth(){
        return _mapper.Map<B>(new A());
    }
}

You can also set up automatic profiles registration like this:

builder.Register(ctx => new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers()))
       .AsImplementedInterfaces()
       .SingleInstance()
       .OnActivating(x => {
           foreach (var profile in x.Context.Resolve<IEnumerable<Profile>>()){
               x.Instance.AddProfile(profile);
           }
       });

Then just register a Profile implementation anywhere in Autofac configuration or in a module to get it hooked up to the configuration.



来源:https://stackoverflow.com/questions/14615607/autofac-3-and-automapper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!