Calling IMappingEngine.Map inside custom mapping

℡╲_俬逩灬. 提交于 2019-12-06 04:32:17

问题


With AutoMapper, when using ConvertUsing to define a custom mapping for a type that is a container, I often need to call IMappingEngine.Map inside the mapping function. This is necessary because it allows-me to reuse the definition of the child mapping.

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

In order to do this, I need a reference to IMappingEngine. When the mapping engine is being configured, I don't have a reference to it that can be captured in the ConvertUsing argument. A simple solution is to have a static reference to it somewhere, but I would like to avoid it.

Is there a way to get a reference to the current IMappingEngine inside a mapping that uses ConvertUsing?


回答1:


This answer is based on your original revision which included additional code

If you take a look at the article by Jimmy Bogard on Automapper and IOC he notes the following:

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.

(There is updated sample IOC code for the latest version of Automapper on github)

As long as your ConfigurationStore is a singleton and requests for IConfiguration and IConfigurationProvider from your DI container resolve to this singleton instance, the article (and code examples) advocates that is fine to create new instances of the MappingEngine when injected.

Based on the above, aside from not registering your ConfigurationStore as a singleton instance (I assume, I'm not familiar with ninject) and not binding this instance to the IConfiguration your final implementation of MappingProfile in your original revision is actually an acceptable solution. It is OK for this to not be the same MappingEngine instance.

However, going by your sample usage in your question it may be worth considering Scenario 2 in the article. If you have no requirement to inject configuration throughout your application and only the IMappingEngine, then you can rely on the static Mapper class for the configuration and lifetime management. In summary your changes to adopt this would be:

  1. Remove the IConfigurationProvider related wiring in the build-up of your container (in the MappingModule).

  2. Switching your MappingProfile to use the static Mapper class

    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. Adding the Profile to the Mapper (perhaps in the MappingModule?), and doing any other configuration through the Mapper:

    Mapper.AddProfile(new MappingProfile());
    
  4. Binding IMappingEngine in the ninject container to the Mapper.Engine property.




回答2:


You can use the static Mapper.Map<IList<OrderItemModel>>(o.Items) instead of your instance of IMappingEngine. It contains a reference to the engine that is lazily instantiated the first time it is used.



来源:https://stackoverflow.com/questions/9282819/calling-imappingengine-map-inside-custom-mapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!