在自定义映射中调用IMappingEngine.Map

使用AutoMapper,当使用ConvertUsing为容器类型定义自定义映射时,我经常需要在映射函数中调用IMappingEngine.Map。 这是必要的,因为它允许我重用子映射的定义。

CreateMap() .ConvertUsing(o => new OrderModel( o.Id, o.ShippingAddress, mapper.Map<IList>(o.Items) )); 

为了做到这一点,我需要一个IMappingEngine的引用。 在配置映射引擎时,我没有可以在ConvertUsing参数中捕获的引用。 一个简单的解决方案是在某个地方有一个静态引用,但我想避免它。

有没有办法在使用ConvertUsing的映射中获取对当前IMappingEngine的引用?

此答案基于您的原始修订版 ,其中包含其他代码

如果您看一下Jimmy Bogard关于Automapper和IOC的文章,他会注意到以下内容:

与Configuration对象不同,MappingEngine不需要任何特殊的缓存/生命周期行为。 MappingEngine非常轻量级,因为它实际上是一些使用Configuration做有趣事情的方法。 如果我们想要,MappingEngine可以是单例,但是没有必要。

(在github上有最新版本的Automapper的更新样本IOC代码)

只要你的ConfigurationStore是一个单例并且从DI容器请求IConfigurationIConfigurationProvider解析为这个单例实例,文章(和代码示例)提倡在注入时创建MappingEngine新实例。

基于上述内容,除了不将ConfigurationStore注册为单例实例(我假设,我不熟悉ninject)并且不将此实例绑定到IConfiguration MappingProfile ,原始版本中的MappingProfile的最终实现实际上是可接受的解决方案。 这可以是不同的MappingEngine实例。

但是,根据您的问题中的示例用法,可能值得考虑文章中的场景2 。 如果您不需要在整个应用程序中注入配置而只需要IMappingEngine ,那么您可以依赖静态Mapper类进行配置和生命周期管理。 总之,您采用此方法的更改将是:

  1. 删除容器构建中的IConfigurationProvider相关连接(在MappingModule )。

  2. 切换MappingProfile以使用静态Mapper

     CreateMap() .ConvertUsing(o => new OrderModel( o.Id, o.ShippingAddress, Mapper.Map>(o.Items) //use static Mapper class )); CreateMap(); 
  3. Profile添加到Mapper (可能在MappingModule ?),并通过Mapper进行任何其他配置:

     Mapper.AddProfile(new MappingProfile()); 
  4. 将ninject容器中的Mapper.Engine绑定到Mapper.Engine属性。

您可以使用静态Mapper.Map>(o.Items)而不是您的IMappingEngine实例。 它包含对第一次使用时懒惰实例化的引擎的引用。