Automapper 是一种匹配类型的方法,理想情况下当您想要映射模型及其视图模型时。 但这与我们在 C# 中使用隐式实现的方法不一样吗? (假设两个模型具有相同的属性但名称不同,此时需要在 AutoMapper 中指定模型之间链接的模型)
有了 autommaper,我们就有了
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 = "[email protected]"
}
EmployeeViewItem viewItem = new EmployeeViewItem();
viewItem.Name = employee.Name;
viewItem.Email = employee.Email;
使用 AutoMapper
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;
}
}
AutoMapper 使用反射来映射属性(轻微的性能开销),允许高级自定义映射规则,并且在基本(常见?)场景中需要 1 行代码。
隐式运算符要求您指定每个属性,很容易出现错误(添加新属性但不将其添加到运算符),更难以设置多种类型,创建大量无用的代码,甚至在最基本的设置中仍然有 N 行代码,其中 N 是属性的数量。
我认为它不言而喻。
我反对使用隐式。
本例中的视图模型没有额外的属性。但是,如果确实如此,那么您根本不需要视图模型。实际上,它还有许多其他属性,可能包含并非来自原始模型的数据。例如。被选中什么的。
隐式转换应该可以在不丢失数据的情况下工作,而通过反向转换回模型是不可能的
第二!
视图模型的目的是匹配视图所需的数据。每个模型应该有多个视图模型。例如。也许您有一个编辑视图和一个不可编辑视图。或移动应用程序和网页!
模型不应该知道这些视图或它们的模型,并且使用隐式需要将其耦合
这取决于您的具体场景。
如果 AutoMapper 能够将您的类相互映射,并且您不需要在映射过程中发生任何特殊逻辑,那么当有东西可以使用 NuGet 为您完成这些操作时,为什么还要自己编写所有代码呢?参考和几行?另外,当您更改类时,此方法会进行调整,从而省去了维护它的麻烦。
如果您需要在映射过程中做 AutoMapper 无法完成的聪明的事情,或者由于某种原因 AutoMapper 在您的项目中不可用,那么您必须编写自己的运算符。如果可以避免,我建议不要这样做,但有时你会坚持下去。
Automapper 基本上可以让你:
但是明显比手写代码慢。因此,如果您不太关心性能 - 您应该尝试一下,它可能是值得的。否则,您可以尝试更快的方法(例如,emitmapper)或手动编写自己的映射器并组合起来转换复杂类型。
我的经验表明,视图模型通常与模型(DTO)非常不同,因为它们是为不同的任务创建的,以解决不同的问题。因此,在这种情况下,自动映射会很困难,或者没有优势(变得难以阅读的混乱、聚集)
每个解决方案都很好,具体取决于场景: