我为Automapper找到的大多数示例都使用静态Mapper对象来管理类型映射。对于我的项目,我需要使用StructureMap注入IMapperEngine作为对象构造的一部分,以便我们可以在单元测试中模拟映射器,因此我们不能使用静态映射器。我还需要支持配置AutoMapper配置文件。
我的问题是我如何配置StructureMap注册表,以便在构建MyService实例时它可以提供IMappingEngine的实例。
这是服务构造函数签名:
public MyService(IMappingEngine mapper, IMyRepository myRepository, ILogger logger)
这是StructureMap注册表
public class MyRegistry : StructureMap.Configuration.DSL.Registry
{
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
//what to do for IMappingEngine?
}
}
我要加载的个人资料
public class MyAutoMapperProfile : AutoMapper.Profile
{
protected override void Configure()
{
this.CreateMap<MyModel, MyDTO>();
}
}
答案 0 :(得分:14)
Mapper
类具有静态属性Mapper.Engine
。使用此命令向容器注册引擎:
For<IMappingEngine>().Use(() => Mapper.Engine);
如果您需要在注入引擎之前加载配置文件,我会将配置代码插入上面的代码段。
<强>更新强>
您的自定义注册表将如下所示
class MyRegistry : Registry
{
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
Mapper.AddProfile(new AutoMapperProfile());
For<IMappingEngine>().Use(() => Mapper.Engine);
}
}
此代码在您的引导程序中运行一次,类型IMappingEngine
的任何依赖项随后将使用您使用自定义Mapper.Engine
配置的静态属性AutoMapperProfile
的值提供。
答案 1 :(得分:7)
将在5.0版中删除静态API。使用a MapperConfiguration实例并根据需要静态存储。使用 CreateMapper用于创建映射器实例。
在新版本(4.2.0&gt; =)中,我们应该通过DI保留并传递 IMapper 。
一个简单的配置服务应该是这样的(ASP.NET核心)
services.AddSingleton<IMapper>(_ => new MapperConfiguration(cfg =>
{
cfg.CreateMap<Foo,Bar>();
})
.CreateMapper());
和我们的服务层(在构造函数注入的帮助下):
public class CrudService<TDocument> : ICrudService<TDocument>
{
private readonly IMapper _internalMapper;
private readonly IRepository<TDocument> _repository;
public CrudService(IRepository<TDocument> repository, IMapper mapper)
{
_internalMapper = mapper;
_repository = repository;
}
public virtual ServiceResult<string> Create<TModel>(TModel foo)
{
var bar = _internalMapper.Map<TDocument>(foo);
try
{
_repository.Create(bar);
}
catch (Exception ex)
{
return ServiceResult<string>.Exception(ex);
}
return ServiceResult<string>.Okay(entity.Id);
}
}
consider TDocument as Bar, and TModel as Foo
更新:
AutoMapper 4.2.1发布 - 静态回归
经过一番反馈和灵魂搜索,老老实实地厌倦了 处理问题时,一些静态API在此恢复 发布。您现在(以及将来)可以使用Mapper.Initialize和 Mapper.Map
答案 2 :(得分:1)
这是我最终得到的结果,因为我无法弄清楚如何在Mapper.Engine上设置配置并将其传递给For()。使用。
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
//type mapping
For<ConfigurationStore>()
.Singleton()
.Use(ctx =>
{
ITypeMapFactory factory = ctx.GetInstance<ITypeMapFactory>();
ConfigurationStore store
= new ConfigurationStore(factory, MapperRegistry.AllMappers());
IConfiguration cfg = store;
cfg.AddProfile<MyAutoMapperProfile>();
store.AssertConfigurationIsValid();
return store;
});
For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IMappingEngine>().Singleton().Use<MappingEngine>();
For<ITypeMapFactory>().Use<TypeMapFactory>();
}
答案 3 :(得分:1)
我写了一篇博文,其中显示了我的AutoMapper和StructureMap设置。我已经为AutoMapper 3.1.0(也适用于3.1.1)和3.0.0和2.2.1创建了特定的注册表。
http://www.martijnburgers.net/post/2013/12/20/My-AutoMapper-setup-for-StructureMap.aspx