【问题标题】:Which is the best approach? AutoMapper against implicit (C# Reference)哪种方法最好? AutoMapper 针对隐式(C# 参考)
【发布时间】:2020-05-24 23:33:36
【问题描述】:

Automapper 是一种匹配类型的方法,理想情况下,当您想要映射模型及其视图模型时。 但这不是我们可以在 C# 中使用隐式实现的相同方法吗? (假设两个模型具有相同的属性但名称不同,这种情况下,您需要在 AutoMapper 中指定模型之间的链接)

有了自动映射器

public class Employee
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class EmployeeViewItem
{
    public string Name { get; set; }
    public string Email { get; set; }
}

通常我们会这样做:

Employee employee = new Employee
{
    Name = "John SMith",
    Email = "john@codearsenal.net"
}

EmployeeViewItem viewItem = new EmployeeViewItem();
viewItem.Name = employee.Name;
viewItem.Email = employee.Email;

使用自动映射器

 EmployeeViewItem employeeVIewItem = Mapper.Map<Employee, EmployeeViewItem>(employee); 

现在,使用隐式 C# 参考

public class Employee
{
    public static implicit operator EmployeeViewItem(Employee employee)
    {
         EmployeeViewItem viewItem = new EmployeeViewItem();
         viewItem.Name = employee.Name;
         viewItem.Email = employee.Email;
         return viewItem;
    }

    public static implicit operator Employee(EmployeeViewItem ev)
    {
        var e = new Employee();
        e.Name = ev.Name;
        e.Email = ev.Email;
        return e;
    }
}

【问题讨论】:

  • 取决于你所说的“更好”。

标签: c# automapper


【解决方案1】:

AutoMapper 使用反射来映射属性(轻微的性能开销),允许高级自定义映射规则,并且在基本(常见?)场景中需要 1 行代码。

隐式运算符要求您指定每个属性,容易出错(添加新属性但不将其添加到运算符),更难为多种类型设置,创建大量无用代码,甚至在最基本的设置你仍然有 N 行代码,其中 N 是属性的数量。

我认为它不言自明。

【讨论】:

  • 实际上是 2N + 6 行;你必须再次映射回来,还有return new Foo 和一些大括号。
  • 好的,但是如果您不能在两个模型中放置相同的属性名称怎么办?
  • 那么这两种方法都需要 1 行代码,所以没有区别。
  • 类型安全呢?在运算符情况下,将在编译时检查投影,而使用反射,类型错误将导致运行时错误。
【解决方案2】:

我对这种隐式的使用说不。

本例中的视图模型没有额外的属性。但是,如果确实如此,您根本不需要视图模型。实际上,它还有许多其他属性,可能包含不是来自原始模型的数据。例如。 IsSelected 什么的。

假设隐式转换可以在不丢失数据的情况下工作,而反向转换回模型是不可能的

其次!

视图模型的目的是匹配视图所需的数据。每个模型应该有多个视图模型。例如。也许你有一个编辑视图和一个不可编辑的视图。或移动应用和网页!

模型不应该知道这些视图或它们的模型,并且使用隐式需要耦合

【讨论】:

  • 最后,你使用隐式的场景是什么?
  • 我真的看不到非值类型的场景。我不认为我会使用它
  • 如果您正在制作自己的特殊值类型,可能是 StarDate 或其他东西
  • 这如何回答这个问题?你说隐式转换应该是同构的,我同意,但这不适用于这个问题,因为模型已经是同构的。假设他们不是。 automapper 如何比显式转换更有用?
【解决方案3】:

这取决于您的特定场景。

如果 AutoMapper 能够将您的类相互映射,并且您不需要在映射过程中发生任何特殊逻辑,那么当有一些东西可以为您完成时,为什么还要自己编写所有代码NuGet 参考和几行?此外,此方法会随着您更改类而适应,从而为您省去维护它的麻烦。

如果您需要在映射过程中做一些 AutoMapper 无法做的聪明事情,或者由于某种原因 AutoMapper 在您的项目中不可用,那么您必须编写自己的运算符。如果可以避免,我建议不要这样做,但有时你会坚持下去。

【讨论】:

    【解决方案4】:

    Automapper 基本上允许您:

    1. 忘记日常琐碎的代码;
    2. 自动处理复杂类型的内部属性;
    3. 在复制构建期间跳过(忽略)某些属性;
    4. 高级:创建对 IOC 友好的映射程序;
    5. 在一处流畅地配置 1-3 个进程。

    但它显然比手写代码慢。因此,如果您不太关心性能 - 您应该尝试一下,它可能是值得的。否则,您可以尝试更快的方法(例如,emitmapper)或手动编写自己的映射器并结合起来转换复杂类型。

    我的经验表明,视图模型通常与模型 (DTO) 非常不同,因为它们是为不同的任务创建的,以解决不同的问题。因此,在这种情况下,自动映射会很困难,或者没有优势(变得难以理解的混乱、聚集)

    【讨论】:

    • IMO 4 和 5 听起来最有用。
    猜你喜欢
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多