Внедрение зависимости в DTO - PullRequest
1 голос
/ 01 декабря 2011

Введение

Я использую ASP.Net MVC3. Мои контроллеры взаимодействуют с уровнем обслуживания, а уровень обслуживания взаимодействует с уровнем доступа к данным, который использует Entity Framework. Я получаю конкретную сущность, используя 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 ]

2 голосов
/ 01 декабря 2011

DTO обычно имеют некоторые свойства и не содержат никакой логики. Вы должны рассмотреть проект, где ваш MVC-контроллер делает что-то вроде этого:

  1. Получить клиента от службы / dataaccess
  2. Рассчитать скидку, вызвав ICalculator, который можно передать контроллеру с помощью инжектора конструктора (или вызвать дополнительную службу, которая выполняет вычисления)
  3. Создайте новый класс модели, который содержит клиента и рассчитанную скидку, и передайте эту модель в представление.
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 голос
/ 01 декабря 2011

Прежде всего: DTO не является моделью представления.

A DTO (объект передачи данных) - это фиктивный класс (на самом деле это не гражданин первого класса (ООП)),Его целью является только выравнивание иерархий и передача информации между различными слоями / уровнями.

A Модель представления используется для адаптации модели (как в MVC), чтобы она лучше подходила к виду.Его цель состоит в том, чтобы просто удалить логику из вида и скрыть детали, касающиеся модели, которые не должны использоваться / доступны в представлении.

Ни DTO, ни ViewModel не следует использовать ни для чего другого, если толькоВы хотите нарушить Принцип единой ответственности .

То, о чем вы просите, должно быть выполнено в вашем контроллере (так как это связующее звено между моделью и представлением).Следовательно, добавьте ICalculator в конструктор вашего контроллера.

...