3

1) В большинстве случаев каждый Aggregate Root должен определить свою собственную транзакционную границу , и в этом случае нам не нужно открывать интерфейс IUnitOfWork в Domain Layer.Нарушение интерфейса IUnitOfWork в слое домена нарушает правило ненасилия?

а) Я предполагаю, что в этой ситуации хороший вариант был бы для repository (используется aggregate для обеспечения invariants применяется в него), чтобы содержать свой собственный экземпляр UoW (при использовании EF, то это UoW экземпляра может быть просто типа DbContext)?

2)

а) Но если по какой-либо причине transaction охватывает несколько aggregates (таким образом, более чем один aggregate должен быть изменен на один раз), то не Domain Layer также должны содержать IUnitOfWork интерфейс?

б) Не подвергая IUnitOfWork интерфейс в Domain Layer нарушают живучесть правило невежество?

с) Если да б), не подвергая затем IUnitOfWork поражение цели с repositories?

Ответ Алексея Рага:

1) I would advice against exposing repositories to aggregates. Repositories are there to give you aggregates, that's it.

а) Хотя я полагаю, что большинство ДДД архитекторов не имеют проблем с обнажая сделок РЕПО с агрегатами (я только с просьбой потому что я прочитал несколько статей о репозиториях и DDD, и впечатление, которое я получил, заключается в том, что авторы не против выставления репозиториев для агрегатов, но теперь я не так уверен)?

b) Итак, вы также не подвергаете размещению репозиториев службам домена?

c) Судя по вашему ответу, я предполагаю, что вы считаете, что выставляете IUnitOfWork как нарушение ПИ?

2) Note that although my command handler (app service in a way)...

ли вы обычно реализации обработчиков команд, как приложение услуг?

3)

public void Handle(ApproveOrderCommand command) 
{ 
    var order = Repository.Get(command.OrderId); 
    property.Approve(command.Comment, ServiceRequiredForOrderApproval); 
    Repository.Save(order); 
} 

property.Approve(...) ли опечатка, и вы на самом деле имел в виду order.Approve(...)?

Thanx заранее

+1

Наличие интерфейса IUnitOfWork как части вашего домена не обязательно является плохим, так же как и ваши интерфейсы репозитория, часть вашего домена тоже не плохо. Пока они явно отличались от вашей реализации. – stephenl

+0

@stephenl: Точка репозитория - это абстрагирование от настойчивости. Но не является ли интерфейс IUnitOfWork самой деталью персистентности и как таковой, введя его в слое домена, мы просочились детали сохранения в уровень домена? – bckpwrld

+1

Интерфейс на самом деле не реализует ничего такого, чтобы поддерживать это в домене нормально. Реализация этого интерфейса может различаться в зависимости от используемого внутреннего хранилища и, следовательно, должна быть внешней для вашего домена. – stephenl

ответ

2

Я бы посоветовал против обнажая репозиториев агрегатов. Хранилища там, чтобы дать вам агрегаты, вот и все.

Посмотрите на это так: ваш домен является «пузырем», который понимает только его собственные вещи. Значит, он понимает только свои собственные объекты ценности, интерфейсы служб домена, которые он объявляет, и т. Д. Я бы не включил репозитории в этом наборе.

Когда ваш домен (агрегат) нуждается в чем-то, он должен явно раскрывать зависимость от того, что ему нужно, а не просто запрашивать какой-либо репозиторий.

Услуги - это то, что объединяет вещи. Например, мой обработчик команды может выглядеть следующим образом:

public class ApproveOrderCommandHandler : IHandle<ApproveOrderCommand> 
{ 
    //this might be set by a DI container, or passed to a constructor 
    public IOrderRepository Repository { get; set; } 
    public ISomeFancyDomainService ServiceRequiredForOrderApproval { get; set; } 

    public void Handle(ApproveOrderCommand command) 
    { 
     var order = Repository.Get(command.OrderId); 
     order.Approve(command.Comment, ServiceRequiredForOrderApproval); 
     Repository.Save(order); 
    } 
} 

Обратите внимание, что, хотя моя команда обработчик (приложение обслуживание в пути) имеет дело с хранилищами, мой домен (порядок агрегат) живучесть невежественна. Он ничего не знает о репозиториях UnitOfWorks.

Когда мне нужно раскрутить UnitOfWork я могу составить это, используя цепочку ответственности шаблона:

public class WithUnitOfWorkHandler<T> : IHandler<T> { 
    private readonly IHandler<T> _innerHandler; 

    public WithUnitOfWorkHandler(IHandler<T> innerHandler) { 
     _innerHandler = innerHandler; 
    } 

    public void Handle(T command) { 
     using(var ouw = new UnitOfWork()) { 
      _innerHandler.Handle(command); 
      uow.Commit(); 
     } 
    } 
} 

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

+0

спасибо за ваш ответ. Можете ли вы ответить на мой ответ? – bckpwrld

+1

Мой ответ, как было задано. a) Нет «DDD-полиция», и вы можете делать все, что хотите, я просто думаю, что разоблачение репозиториев _domain_ (не только агрегатов) нелогичный. n должно явно объявлять свои зависимости _ в языке домена, а не некоторые репозитории. b) Как правило, да, поскольку они являются частью домена и говорят на языке домена. Зависимости предоставляются им. c) Не совсем так, поскольку реализации 'UnitOfWork' и репозиториев не являются« внутри »домена, поэтому домен остается PI. –

+1

2) Обычно да, я смотрю на обработчики команд, как и на мои приложения, потому что любой _action_ является результатом некоторой команды. 3) Да, это опечатка. Я копировал и забыл изменить имя :) –

2

Несовершенство сохранения: деловой уровень не имеет знаний и никакой зависимости от конкретной системы сохранения, которая используется под капотом (например, MS SQL Server, Oracle, файлы XML, что угодно).

Таким образом, выставляя интерфейс, который абстрагирует конкретный тип хранилища данных, он никогда не может нарушить этот принцип.

+0

Я предположил, что даже разоблачение UoW-интерфейса в доменах или слоях услуг было нарушением PI, поскольку интерфейс UoW содержит язык, основанный на сохранении, и, таким образом, как детали, связанные с сохранением, просочились в уровни обслуживания/домена (хотя я знаю два слои не знают конкретных реализаций UoW) – bckpwrld

1

Сохранение Незнание - это руководство, практически невозможно достичь с помощью реальных языков и технологий. Шаблон репозитория и блок работы абстрагируют материал, связанный с сохранением, и «скрывают» уровень доступа к данным в бизнес-коде, но это скорее трюк (чистый), чем абсолютное решение. Наличие или необходимость чего-то (интерфейс, базовый класс, атрибут ...), который гласит: «Хейи, есть что-то здесь, мы хотим скрыть ...», нарушает ПИ. Но на данный момент лучшего решения нет.