将依赖注入DTO

时间:2011-12-01 12:58:33

标签: c# asp.net-mvc dependency-injection inversion-of-control autofac

简介

我正在使用ASP.Net MVC3。我的控制器与服务层进行通信,服务层与使用实体框架的数据访问层进行通信。 我使用Entity Framework获得了一个特定的实体。该实体转换为DTO。然后我将这个DTO交付给MVC控制器。像这样:

伪代码:

// This is inside my Service Layer
var entity = DataAccess.GetById(id);
var dto = createDtoWithValuesFrom(entity);
return dto; // Return dto to MVC controller

在这个DTO中,我想使用依赖项,例如计算器。让我们说我的DTO看起来像这样:

public class Customer
{
  private ICalculator Calculator;

  public class Customer(ICalculator calculator)
  {
     Calculator = calculator;
  }

  public string Name { get; set; }
  public decimal Discount
  {
     get
     {
        return Calculator.Discount();
     }
  }
}

问题

如何实现我的DTO,让Autofac注入计算器? 我可以想办法做到这一点:

var calculator = DependencyResolver.Current.GetService<ICalculator>;
var dto = new DTO(calculator );

但是我不知道这是否是最好的方法,因为它闻起来像ServiceLocator,而且我已经读过它不喜欢使用它。

2 个答案:

答案 0 :(得分:2)

DTO通常具有一些属性,不包含任何逻辑。 您应该考虑MVC-Controller执行以下操作的设计:

  1. 从service / dataaccess获取客户
  2. 通过调用ICalculator计算折扣,ICalculator可以使用构造函数注入传递给Controller(或调用一个额外的服务进行计算)。
  3. 创建一个包含客户和计算折扣的新模型类,并将此模型传递给视图。
  4. public class Model
    {
      public Customer Customer { get; set; }
    
      public double Discount { get; set; }
    }
    
    public class SomeController : Controller
    {
      private readonly DataAccess dataAccess;
      private readonly ICalculator calculator;
    
      public SomeController(DataAccess dataAccess, ICalculator calculator)
      {
        this.dataAccess = dataAccess;
        this.calculator = calculator;
      }
    
      public ActionResult Index(int id)
      {
        var model = new Model();
        model.Customer = this.dataAccess.Get(id);
        model.Discount = this.calculator.Calculate(customer);
    
        return View(model);
      }
    }
    

答案 1 :(得分:1)

首先:DTO不是视图模型。

DTO (数据传输对象)是一个虚拟类(它实际上不是第一类(OOP)公民)。它的目的只是在不同的层/层之间展平层次结构和传输信息。

视图模型用于调整模型(如在MVC中),以便更好地适应视图。它的目的只是从视图中删除逻辑并隐藏有关模型的细节,这些细节不应在视图中使用/可用。

除非您想要违反Single Responsibility Principle,否则DTOViewModel不得用于其他任何内容。

您要求的内容应该在您的控制器中完成(因为它是模型和视图之间的粘合剂)。因此,将ICalculator添加到控制器的构造函数中。