Autofac 3 и Automapper

Кто-нибудь знает исчерпывающее руководство по настройке Automapper с Autofac. Я новичок в обоих, но я поиграл со статическим классом Mapper, однако я хочу иметь возможность имитировать и внедрять IMappingEngine и создавать конфигурацию, которая устанавливает все мои отображения. Все руководства, на которые я смотрел до сих пор, на самом деле не объясняют, что происходит, и я не могу понять это. Также я использую Autofac 3.0, который, кажется, имеет некоторые отличия в методах ContainerBuilder, что не помогает (причина, по которой я его использую, заключается в том, что от него зависит Autofac.mvc4).

Обновить:

Хорошо, простое решение, кажется, работает достаточно хорошо, однако я нигде не видел его в Интернете, и, может быть, по уважительной причине, которую я не знаю? Самое простое, что можно сделать, это просто зарегистрировать статический Mapper.Engine как IMappingEngine и по-прежнему использовать статический Mapper.CreateMap для настройки в первую очередь.

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

Теперь Autofac может внедрить IMappingEngine в ваши конструкторы. Это означает, что Mapper будет обрабатывать синглтон IMappingEngine, а не Autofac, а Autofac просто действует как обертка для него. Я хотел бы, чтобы Autofac обрабатывал экземпляр IMappingEngine, но я не уверен, как?

1 ответ

Решение

Ваше простое решение в порядке, при условии, что вы не хотите высмеивать маппер в модульных тестах или создавать мапперы с модифицированными конфигурациями для вложенных областей действия времени жизни (последний мне кажется немного странным, но кто знает).

Если вам это нужно, вы можете взять некоторые фрагменты кода из Mapperкомпоненты класса и регистра, такие как:

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

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

Я не уверен, если вам действительно нужно сделать IMappingEngine синглтон. Он должен быть достаточно легким для создания в зависимости.

Теперь вы можете использовать это так:

// 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());
    }
}

Вы также можете настроить автоматическую регистрацию профилей следующим образом:

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);
           }
       });

Тогда просто зарегистрируйте Profile реализация в любом месте в конфигурации Autofac или в модуле, чтобы подключить его к конфигурации.

Другие вопросы по тегам