C# 我应该把自动映射代码放在哪里?

C# 我应该把自动映射代码放在哪里?,c#,automapper,C#,Automapper,我正在Asp.NETMVC应用程序中使用Automapper。 关于automapper的使用,我有一个问题 从大量示例代码中,我看到人们直接使用mappermapper.Map(source)进行操作,我不确定这是否是一个好方法,在我看来,我希望将mapper代码包装在代理对象中,而不是让它直接与controller对话 public BankflowData CreateBankflowAdjustments(BankflowData addedBankFlow) {

我正在Asp.NETMVC应用程序中使用Automapper。 关于automapper的使用,我有一个问题

从大量示例代码中,我看到人们直接使用mapper
mapper.Map(source)
进行操作,我不确定这是否是一个好方法,在我看来,我希望将
mapper
代码包装在代理对象中,而不是让它直接与
controller
对话

      public BankflowData CreateBankflowAdjustments(BankflowData addedBankFlow)
      {
         var bankflow = Mapper.Map<Bankflow>(addedBankFlow);
         var newBankflow = Underlying.CreateBankFlowAdjustments(bankflow);
         return Mapper.Map<BankflowData>(newBankflow);
      }
公共银行流量数据创建银行流量调整(银行流量数据添加银行流量)
{
var bankflow=Mapper.Map(addedBankFlow);
var newBankflow=基础.CreateBankFlowAdjustments(bankflow);
返回Mapper.Map(newBankflow);
}
在本例中,控制器对类
Bankflow
一无所知,只知道dto
BankflowData


我想知道对于使用AutoMapper的应用程序来说,这是否是一种良好的做法?

对于前面的问题,我回答道

我在回答时解释说:

[…]我有这样一个典型的结构:

public static class Mapping
{
public static BankflowData CreateBankflowAdjustments(this BankflowData addedBankFlow)
      {
         var bankflow = Mapper.Map<Bankflow>(addedBankFlow);
         var newBankflow = Underlying.CreateBankFlowAdjustments(bankflow);
         return Mapper.Map<BankflowData>(newBankflow);
      }
}
  • MyProject.Core
  • MyProject.Domain
  • MyProject.DependencyInjection
  • 我的项目.基础设施
  • MyProject.Web
  • 我的项目。测试
基础设施层包含有关日志记录、电子邮件发送和数据访问的信息。它将包含我的选择。它不是业务逻辑的东西,也不是UI的东西。这是我解决问题的方法。它在外层,但它只参考核心

在我的例子中,基础设施层也包含Automapper。核心定义了一个简单的接口(比如说,
IAutoMapper
),基础设施中存在的一个简单对象实现了它,该对象可以通过依赖项注入传递到UI层

然而吉米·博加德(Automapper的创始人)在

[…]如果你抱怨UI项目不应该直接引用这个库,因为一些愚蠢的假建筑师的原因(甚至引用某个臭烘烘的圆形蔬菜),我会开车到你家打你一巴掌。放下架子,开始提高工作效率。


据我所知,他的意思是可以从UI层引用Automapper。当然,当他说“某个发臭的圆形蔬菜”时,他指的是Jimmy不太喜欢的东西。

如果应用程序中有服务层,最好将automapper放在服务层。在任何情况下,请尝试使用扩展方法通过automapper映射对象,如下所示:

public static class Mapping
{
public static BankflowData CreateBankflowAdjustments(this BankflowData addedBankFlow)
      {
         var bankflow = Mapper.Map<Bankflow>(addedBankFlow);
         var newBankflow = Underlying.CreateBankFlowAdjustments(bankflow);
         return Mapper.Map<BankflowData>(newBankflow);
      }
}
公共静态类映射
{
公共静态BankflowData CreateBankflowAdjustments(此BankflowData添加了BankFlow)
{
var bankflow=Mapper.Map(addedBankFlow);
var newBankflow=基础.CreateBankFlowAdjustments(bankflow);
返回Mapper.Map(newBankflow);
}
}

它将使您的代码更具可读性,并将分离您的关注点。获取更多信息

感谢您的回答,是的,我同意您使用简单的界面将非业务逻辑代码放入基础架构和包装器自动映射器中,但我的问题是我是否应该直接向控制器公开域?或者通过代理对象进行包装,并且只向控制器公开DTO?例如:我有一个服务对象,它返回域对象
Cashflow
,这是一个相当大的对象,也就是说,虽然我有一个DTO对象CashflowDTO,这是一个轻量级对象,但服务对象只将域对象作为参数或结果,所以我有两个样式,1。将dto映射到控制器层(我不喜欢)2中的域对象。使用代理对象和映射数据的包装服务器,我更喜欢第二种选择,你的想法是什么?我总是从UI使用AutoMapper,因为UI获得了ViewModel,从那里我将映射值发送到服务层,服务层继续进行业务逻辑,等等。我还有一个InnerCore=>ViewModel=>Services,其中我只在将结果发送到服务层之前执行一些暗示ViewModel的操作。事情进展得很顺利。这个例子看起来不错,所以您的想法是使用extend方法封装
Mapper.Map
并调用DTO.ToDomain(),对吗?您也同意映射器代码应该放在服务层而不是控制器层,对吗?是的,但如果您有服务层,最好将它们放在那里,因为将DTO或ViewModel映射到域实体的最佳位置是服务层。虽然若你们的应用程序不够大,你们可以把它们放在你们的控制器中,但你们可以尝试使用扩展方法来使你们的代码干净。