Dto и доменные объекты. Я правильно создал свой dto? - PullRequest
1 голос
/ 09 августа 2010

У меня есть следующая сущность домена:

public class CartItem
{
    public virtual Guid Id { get; set; }
    public virtual Guid SessionId  { get; set; }
    public virtual int Quantity  { get; set; }
    public virtual Product Product  { get; set; }
}

У меня есть следующий DTO:

public class CartItemDTO
{
    public CartItemDTO(CartItem cartItem)
    {
        Id = cartItem.Id;
        Quantity = cartItem.Quantity;
        Name = cartItem.Product.Name;
        Price = cartItem.Product.Price;
    }

    public Guid Id { get; private set; }
    public int Quantity { get; private set; }
    public string Name { get; private set; }
    public decimal Price { get; private set; }
}

Текущий рабочий процесс довольно прост: мой репозиторий возвращает IEnumerable типа CartItem,Мой сервис преобразует его в dto (CartItemDTO).Мой контроллер затем передает его на просмотр.Пока все хорошо.

Теперь я хочу добавить итоги для каждой позиции.Я добавил следующее свойство в CartItemDTO.

public decimal Total { get; private set; }

Затем я добавил следующий код в конструктор CartItemDTO.

Total = cartItem.Quantity * cartItem.Product.Price;

Мой первый вопрос , если этоподход лучшей практики?Если нет, то почему?Должен ли я добавить свойство Total где-нибудь еще?Если да, то почему?

Я также хотел реализовать итоговое значение для всей корзины, поэтому я создал новый класс (ниже) и изменил свой сервис для его возврата.

public class CartItemResult
{
    public CartItemResult(IEnumerable<CartItemDTO> result)
    {
        CartItems = new List<CartItemDTO>(result);
        Total = result.Sum(total => total.Total);
    }

    public IList<CartItemDTO> CartItems { get; private set; }
    public decimal Total { get; private set; }
}

Я мог быТеперь либо передайте новый класс в представление, либо создайте отдельную ViewModel и передайте содержимое нового класса в ViewModel и передайте его представлению.

Мой второй вопрос сноваесли этот подход является подходом передовой практики?Если нет, то почему и что я должен был сделать по-другому?

Ответы [ 2 ]

5 голосов
/ 10 августа 2010

DTO - чистый класс для передачи данных.Он не должен содержать никакой логики.Вы добавили тег управления доменом, поэтому я думаю, что вы хотите использовать доменные объекты и доменные службы.Ваш объект домена (CartItem) несет ответственность за вычисление итоговой суммы товара.Доменный объект - это данные + бизнес-логика и правила, работающие с этими данными.Вычисление итогов - бизнес-логика.Также для вашей второй части (CartItemResult) это обычно обрабатывается чем-то, называемым доменной службой.Служба домена обеспечивает бизнес-логику, которая не связана с одним объектом домена, а работает со многими объектами домена.

Но вам также следует подумать о сложности вашего проекта.Тебе это действительно нужно?Не используйте шаблоны только потому, что они существуют, всегда находите причину их использовать.Подход, упомянутый Дэвидом Нилом, также подходит для некоторых приложений.

С наилучшими пожеланиями, Ладислав

3 голосов
/ 09 августа 2010

Лично для извлечения данных я бы предложил вернуть объект POCO из хранилища и отобразить его на ViewModel в контроллере ( Automapper ). На самом деле нет необходимости иметь промежуточный объект.

Именно в вашем проекте должно быть реализовано свойство Total. Используется ли это свойство в домене для какой-либо бизнес-логики? Может ли это быть? Если нет, то вы можете считать это просто проблемой презентации и подходящей для ViewModel.

Для обновления данных - вернуть что-то вроде CartItemUpdateViewModel в вашем пользовательском интерфейсе, который сопоставляется с сущностью домена CartItemUpdateDetails в контроллере, который затем передается методу хранилища.

Насколько ваш вопрос относительно CartItemResult идет. Я бы лично поместил логику Total во ViewModel и заполнил эту ViewModel в контроллере из метода репозитория, возвращая IEnumerable<CartItem>.

Взгляните на проект WhoCanHelpMe для хорошего корпоративного приложения, демонстрирующего DDD.

...