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 или в модуле, чтобы подключить его к конфигурации.