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

问题描述:

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

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

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

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

+0

只是好奇,为什么这被标记为依赖注入? – 2012-02-22 01:04:26

+0

这是一个错误。感谢您的注意。我重写了这个问题并删除了它的一部分,因为它使它更加复杂。基本上,使用依赖注入来创建映射器及其配置时,这个问题会变得更加明显。 – 2012-02-22 11:28:54

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

+1

是的,可行,但我宁愿避免使用静态的Mapper类。 – 2012-02-23 10:07:11

+0

相同,没有找到解决方案要么 – juFo 2016-02-02 08:33:01

这个答案是基于您original revision其中包括额外的代码

如果你看一看上Automapper and IOC文章吉米·博加德他指出以下几点:

的MappingEngine,不像我们的配置对象,不需要任何 特殊的缓存/生命周期行为。 MappingEngine非常轻便,因为它实际上是一些使用Configuration进行有趣的事情 的事情。如果我们想要,MappingEngine可以是singleton,但是不需要。

(用于Automapper对github最新版本有更新样本IOC代码)

只要你ConfigurationStore是从您的DI容器决心IConfigurationIConfigurationProvider独立的,并要求该单件实例,该文章(和代码示例)主张在注入时可以创建MappingEngine的新实例。

从没有注册您的ConfigurationStore作为单一实例(我假设,我不熟悉ninject)和该实例在原始版本不具约束力的IConfiguration最终实现MappingProfile基于上述,除了实际上是可接受的解决方案这可以不是相同的MappingEngine实例。

但是,通过您的问题中的示例用法,可能值得考虑场景2在文章中。如果您不需要在整个应用程序中注入配置,并且只需要注入IMappingEngine,则可以依靠静态Mapper类进行配置和生命周期管理。综上所述更改采纳,这将是:

  1. 在容器中的积聚(在MappingModule)拆下IConfigurationProvider系统布线。

  2. 切换您的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>(); 
    
  3. 添加ProfileMapper(在MappingModule吧?),和做通过Mapper任何其他配置:

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

+0

主要问题是,为了创建一个IMappingEngine,我需要一个IConfiguration,但是要创建IConfiguration,我需要IMappingEngine。使用静态映射器隐藏了这个问题,但没有解决它。我可以创建一个空配置,使用它创建映射引擎,然后使用映射引擎配置配置,但这依赖于MappingEngine在实例化后接受配置更改的事实。 – 2012-02-23 10:12:06

+0

我不确定我关注。这些地图只是在映射实例时执行的一系列lambda表达式。只要嵌套地图中的MappingEngine使用了正在配置的同一个ConfigurationStore(即单例),那么它在映射时就不成问题了。正如你在'Profile'中完成的那样,你可以用'CreateMap'来定义它们的用法。 – 2012-02-23 17:18:06