使用AutoMapper,当使用ConvertUsing为作为容器的类型定义自定义映射时,我经常需要在映射函数内调用IMappingEngine.Map.这是必要的,因为它允许我重用子映射的定义.
CreateMap<Order, OrderModel>()
.ConvertUsing(o => new OrderModel(
o.Id,
o.ShippingAddress,
mapper.Map<IList<OrderItemModel>>(o.Items)
));
为了做到这一点,我需要一个IMappingEngine的引用.在配置映射引擎时,我没有可以在ConvertUsing参数中捕获的引用.一个简单的解决方案是在某处有一个静态引用,但我想避免它.
有没有办法在使用ConvertUsing的映射中获取对当前IMappingEngine的引用?
解决方法:
此答案基于您的original revision,其中包含其他代码
如果你看看Jimmy Bogard在Automapper and IOC年的文章,他会注意到以下几点:
The MappingEngine, unlike our Configuration object, does not need any
special caching/lifetime behavior. The MappingEngine is very
lightweight, as it’s really a bunch of methods doing interesting
things with Configuration. MappingEngine can be singleton if we want,
but there’s no need.
(在github上有最新版本的Automapper的更新样本IOC代码)
只要你的ConfigurationStore是一个单例并且从DI容器请求IConfiguration和IConfigurationProvider解析为这个单例实例,文章(和代码示例)提倡在注入时创建MappingEngine的新实例.
基于以上所述,除了不将ConfigurationStore注册为单例实例(我假设,我不熟悉ninject)并且不将此实例绑定到IConfiguration,原始版本中的MappingProfile的最终实现实际上是可接受的解决方案.这可以是不同的MappingEngine实例.
但是,根据您的问题中的示例用法,可能值得考虑文章中的场景2.如果您不需要在整个应用程序和IMappingEngine中注入配置,那么您可以依赖静态Mapper类进行配置和生命周期管理.总之,您采用此方法的更改将是:
>在容器的构建中删除IConfigurationProvider相关的接线(在MappingModule中).
>切换MappingProfile以使用静态Mapper类
CreateMap<Order, OrderModel>()
.ConvertUsing(o => new OrderModel(
o.Id,
o.ShippingAddress,
Mapper.Map<IList<OrderItemModel>>(o.Items) //use static Mapper class
));
CreateMap<OrderItem, OrderItemModel>();
>将配置文件添加到Mapper(可能在MappingModule中?),并通过Mapper进行任何其他配置:
Mapper.AddProfile(new MappingProfile());
>将ninject容器中的IMappingEngine绑定到Mapper.Engine属性.