【问题标题】:How to reuse ValueResolver across different mappings in AutoMapper 5?如何在 AutoMapper 5 中跨不同映射重用 ValueResolver?
【发布时间】:2016-07-13 12:50:55
【问题描述】:

我刚刚尝试将 AutoMapper 升级到 5.0.2,但遇到了障碍。

根据migration docs,值解析器现在可以访问目标对象:

值解析器的签名已更改,以允许访问源/目标模型。

这导致每个值解析器都与一个目标类型绑定。

但是,我们的一些值解析器用于多种目标类型。我们有例如在映射我们 DTO 的所有 ID 属性期间使用的解析器。解析器通过注入解析器的服务来修改 ID。

如何在 AutoMapper 5 中定义可重用的值解析器,这样我就不必为每个目标类型创建具有完全相同实现的专用解析器?

注意:使用值解析器而不是直接操作值的主要原因是依赖注入。根据this answer,值解析器是在映射期间使用依赖注入服务的最佳方式。

【问题讨论】:

    标签: automapper automapper-5


    【解决方案1】:

    目标类型可以只是“对象”:

    public class FooResolver : IValueResolver<object, object, string> {}
    

    或者可以更具体:

    public class FooResolver : IValueResolver<IEntity, object, string> {}
    

    由于为 IValueResolver 定义的差异,您可以将基类型放在前两个通用参数中。

    【讨论】:

    • 谢谢,第一个问题解决了。 .ForMember() 的替代品是什么,它允许我选择值解析器应该处理的成员?我有多个名称不同的成员,但总是想使用相同的值解析器(例如,有时称为Id,在其他地方称为UserId)。
    • 你想要一个 IMemberValueResolver:github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide
    【解决方案2】:

    美好的一天,我认为最好的方法是使用泛型,如下所示:

    public class FooResolver<TSource, TDestination> : IValueResolver<TSource, TDestination, string>
    {
       private readonly Dictionary<Type, int> typeDictionary;
    
       public FooResolver()
       {
          typeDictionary = new  Dictionary<Type, int>
         {
            {typeof(FooA), 0},
            {typeof(FooB), 1}
         };
       }
    
       pulic string Resolve(TSource source, TDestination destination, string destMember, 
       ResolutionContext context)
       {
          switch (typeDictionary[source.GetType()])
          {
             case 0:
               var fooA = ((FooA)Convert.ChangeType(source, typeof(FooA)));
               //custom code
             break;
             case 1:
               var fooB = ((FooB)Convert.ChangeType(source, typeof(FooB)));
               //custom code
             break;
          }
    
          return string_value;
       }
    }
    

    在映射期间,您只需提供源和目标的实际类型,例如 act.MapFrom&lt;FooResolver&lt;FooA, FooADestination&gt;&gt;

    【讨论】:

    • 请问这个答案有什么问题吗?我现在很沮丧地回答问题。 IValueResolver&lt;object, object, string&gt;,有了这个,我如何获取对象属性?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2014-09-23
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多