使用automapper有什么好处?

Kat*_*nis 6 mapping automapper object-object-mapping

我的问题可能很愚蠢,但我很确定我会错过这个问题的一个非常重要的部分.我必须做一些对象到对象映射(在C#项目中使用的域类和发送到闪存客户端的类之间).

我的第一选择是Automapper.但我有一些问题(嵌套属性,而不是无定义的构造函数定义).事实证明,用automapper映射一个非常复杂的类型并不容易.

然后我的问题是:为什么不实现像这样的方法:

  ClassA GetClassAByClassB(ClassB pObj)

   {  
     ClassA objA = new ClassA();  
     objA.Prop1 = pObj.Prop1;  
     objA.NestedType.Prop2 = pObj.Prop2;  
     //....Some more.....  
     return objA;  
   }  
Run Code Online (Sandbox Code Playgroud)

它具有与使用Automapper完成的映射完全相同的灵活性.您仍然必须提供源对象中的哪个属性被复制到目标对象中的哪些属性.你只需使用'='而不是lambda表达式.

但是,如果您在域类中更改某些内容,则无论如何都必须更改此"映射"部分.那么说服我使用Automapper的主要原因是什么(正如我在开头说的那样,我很确定我错过了一些重要的东西).

Xia*_* Ge 7

AutoMapper 声称的一大好处是按约定进行映射。这里引用《AutoMapper简介和示例》

AutoMapper 的美妙之处就在于此。当您的类按照常规方式自行对齐时,您的映射配置可以非常简单

这是有代价的。重命名或更改目标或源属性名称将破坏映射并引入运行时错误。

如果不使用按约定映射,AutoMapper 就会失去其优势。在这种情况下,我宁愿编写一个像这样的工厂函数。

public static ClassA MapToClassA(this ClassB b) => 
    new ClassA()
    {
        propA = b.propA;
        propB = b.propB;
        propC = b.propC;
    }
Run Code Online (Sandbox Code Playgroud)

然后你将构造目标对象,例如

var classA = classB.MapToClassA();
Run Code Online (Sandbox Code Playgroud)

代替

var classA = Mapper.Map<ClassB, ClassA>(classB)
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我更喜欢工厂函数,因为它的明确性、可读性和调试友好性。祝你好运,在第二种情况下,尝试找出如何ClassB映射到ClassA、是否加载映射配置文件、或者为什么在调用函数时出现异常Map<>()、或者为什么某些属性被分配了错误的值。


小智 7

有时使用映射器,很难追踪错误。例如,如果我们将数据类中的 Employee 与视图模型类中的 Emplyee 拼写错误,则像小型映射器这样的映射器不会抛出任何异常,除非我们显式地将映射器设置为严格映射,并且在此期间代码可以完美编译和运行,但我们无法追踪错误。这种情况在手动映射中很少发生,因此手动映射对象比自动映射有一些优势。

  • 我正在第二天尝试调试为什么自动映射器没有应用转换。 (2认同)

Jak*_*cki 6

因为使用 AutoMapper,您不必实现这些方法;-)

你的方法需要写很多

classA.propA = classB.propA;
classA.propB = classB.propB;
classA.propC = classB.propC;
classA.propD = classB.propD;
classA.propE = classB.propE;
Run Code Online (Sandbox Code Playgroud)

AutoMapper 使用约定来计算它本身。更重要的是,您不必担心pObj == null(在这种情况下您的代码将抛出NulLReferenceException异常)。

您还可以在映射中定义转换(即字符串到日期时间)。

Mapper.CreateMap<User, UserModel>().ForMember(d => d.LastLogin, c => c.MapFrom<DateTime?>(u => u.Credential.LastLogin));
Run Code Online (Sandbox Code Playgroud)

AutoMapper 也支持嵌套属性。

在这里阅读更多内容:AutoMapper 简介和示例