Дизайн, управляемый доменом, с Entity Framework и шаблоном репозитория

Раньше я имел дело с простыми приложениями, в которых есть Service Layer, содержащий всю бизнес-логику. В Domain Driven Design принято хранить бизнес-логику в богатой модели.

Просмотрел руководство Pluralsight, в котором они упоминают Репозитории, и заметил, что репозиторий обычно содержит основные операции CRUD (создание, обновление, выборка и удаление объектов). Ничего особенного в отношении Entity Framework не объяснялось.

Entity Framework 6 и Entity Framework Core уже предоставляют Repository/UoW из коробки. Мне интересно, можно ли в этом случае не создавать уровень репозитория?

Итак, как я себе представляю приложение без отдельного слоя репозитория...

Мое понимание:

Например, у нас есть модель Customer в качестве сводного корня (богатая модель предметной области). И эта модель имеет отношение «один ко многим» ICollection<Payment> Payments. Плюс, согласно DDD — мы храним нашу логику внутри модели — так что у нас есть метод MakePayment.

Код будет следующим:

public class Customer
{
    public virtual ICollection<Payment> Payments { get; set; }

    // ... other properties/collections

    public void MakePayment(decimal amount)
    {
        this.Payments.Add(new Payment() { Amount = amount });
    }
}

С помощью Entity Framework мы можем нетерпеливо загрузить все дерево с результатом Customer, в котором уже сопоставлены все их Payments.

(скажем, мы имеем дело с приложением ASP.NET WebAPI)

Итак, чтобы произвести оплату, я думаю, мы делаем следующее:

  1. в нашем контроллере/сервисе получаем клиента (например по id)

  2. затем следует код customer.MakePayment(10);

  3. после этого мы вызываем метод dbContext.SaveChanges()

  4. DbContext отслеживает изменения и сохраняет платеж — Бинго!

Правильно ли я понимаю?


Что касается сервисного уровня:

Можно ли использовать сервисный уровень с DDD в таком веб-приложении?

Я по-прежнему считаю, что хранить код в контроллере не обязательно правильно (даже с DDD), если, например, часть функций МОЖЕТ БЫТЬ востребована в приложении WPF, поэтому мы можем использовать с ней сервисный уровень.

Кажется, это самый оптимальный подход, не так ли?


person Alex Herman    schedule 27.12.2018    source источник
comment
Этот вопрос слишком широк / основан на мнениях, но, по моему мнению, вы на правильном пути. Дополнительное репо — нет, сервисный уровень — да, DDD с объектами класса EF: возможно.   -  person Gert Arnold    schedule 28.12.2018
comment
Я ценю ваш быстрый ответ @GertArnold. Но я не думаю, что это слишком широко... Entity Framework и другие фреймворки развиваются, и, ИМХО, у разработчиков, которые начинают изучать DDD, используя немного устаревшие учебные пособия, все больше и больше путаницы. Еще раз спасибо!   -  person Alex Herman    schedule 28.12.2018
comment
некоторые туториалы стоят даже недешево, и они до сих пор не освещают важных аспектов с учетом современного стека ПО :)   -  person Alex Herman    schedule 28.12.2018
comment
Это было не раньше, чем влиятельные лица, такие как Айенде Рахиен, начали открыто критиковать шаблон. что сообщество разработчиков постепенно начало воспринимать идею, без которой мы, возможно, могли бы обойтись. И, как вы сказали, с ORM, такими как EF, это дополнительный уровень репо, что делает его еще более сомнительным.   -  person Gert Arnold    schedule 28.12.2018


Ответы (2)


Мне интересно, можем ли мы в этом случае не создавать слой репозитория?

Как объяснялось в первом абзаце здесь, рассмотрите возможность использования универсального репозитория (DbSet) напрямую. Избегайте создания дополнительного слоя репозитория.

Правильно ли я понимаю?

IMO, ваше понимание правильное, если вы правильно реализовали шаблон Unit of Work (Session Per Request, как вы объяснили в вопросе). Вот как это должно работать.

Можно ли использовать сервисный уровень с DDD в таком веб-приложении?

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


С DDD рассмотрите возможность использования CQRS. С помощью CQRS вы разделяете операции чтения и записи в хранилище данных. Репозиторий в этом случае необязателен. Как было предложено выше, вы можете использовать общий репозиторий, предоставляемый ORM.

person Amit Joshi    schedule 28.12.2018

Мне интересно, можно ли в этом случае не создавать уровень репозитория?

На мой взгляд, вы не можете пропустить слой репозитория. Как правило, Репозиторий отвечает за сохранение и перестроение совокупного корня, и объект вашего домена не является объектом вашей базы данных. Сущность EF не является сущностью вашего домена.

Можно ли использовать сервисный уровень с DDD в таком веб-приложении?

Конечно, вы можете сохранить свой Сервисный уровень, на самом деле вы можете назвать его Прикладной уровень в DDD, но вам нужно позаботиться о том, что должно быть включено в этот уровень.

person YonF    schedule 28.12.2018