DDD: Къде да съхранявате интерфейсите на домейна, инфраструктурата?

Има ли смисъл да групирате всички интерфейси на вашия домейн слой (модули, модели, обекти, домейн услуги и т.н.) всички в рамките на инфраструктурния слой? Ако не, има ли смисъл да се създаде "споделен" проект/компонент, който групира всичко това в споделена библиотека? В края на краищата дефиницията на „инфраструктурен слой“ включва „споделени библиотеки за слоеве на домейн, приложение и потребителски интерфейс“.

Мисля да проектирам кодовата си база около DDD слоевете: потребителски интерфейс, приложение, домейн, инфраструктура. Това би създало 4 проекта с уважение. Мисълта ми е, че препращате към инфраструктурния слой от домейн слоя. Но ако дефинирате интерфейсите в проекта Domain Layer, да речем за IPost, тогава ще имате кръгова препратка, когато трябва да препратите към проекта Domain Layer от проекта Infrastructure, когато дефинирате метода IPostRepository.Save(IPost post) . Следователно идеята за „дефиниране на всички интерфейси в споделената библиотека“.

Може би хранилищата не трябва да очакват обект за запис (IPostRepository.Save(IPost post); но вместо това очаквайте параметрите на обекта (това обаче може да бъде дълъг набор от параметри в Save()). Като се има предвид, това може да бъде идеална ситуация, която показва кога даден обект става прекалено сложен и трябва да се търсят допълнителни стойностни обекти за него.

мисли?


person eduncan911    schedule 28.03.2009    source източник


Отговори (3)


Относно къде да поставя хранилищата, лично аз винаги поставям хранилищата в специален инфраструктурен слой (напр. MyApp.Data.Oracle), но декларирам интерфейсите, на които хранилищата трябва да отговарят, в слоя на домейна.
В моите проекти приложният слой трябва да има достъп до домейна и инфраструктурния слой, защото е отговорен за конфигурирането на домейна и инфраструктурния слой.
Приложният слой е отговорен за инжектирането на правилната инфраструктура в домейна. Домейнът не знае с коя инфраструктура говори, той знае само как да я извика. Разбира се, използвам IOC контейнери като Structuremap, за да инжектирам зависимостите в домейна. Отново не твърдя, че това е начинът, по който DDD препоръчва да структурирате вашите проекти, това е просто начинът, аз архитектурирам приложенията си. наздраве

person Geo    schedule 01.04.2009
comment
Отличен Geobarteam. Това просто ми даде страхотен момент. Да, дефинирайте интерфейси в домейна, хранилищата трябва да бъдат внедрени в отделни сборки (MySqlProviver, MsSqlProvider, XmlProvider и т.н.). И някакъв тип IOC контейнер (Castle Windsor, който обичам), използван за свързването му към слоя на приложението. перфектен - person eduncan911; 01.04.2009
comment
В случая на ASP.NET MVC всъщност е лесно да се инжектира хранилището в контролера (UI слой) чрез Castle Windosr. Стивън Сандерсън имаше добър пример за това в ASP.NET MVC Framework Preview. В книгата Domain-Driven Design Quickly, която имам, се казва, че потребителският интерфейс, приложението и домейнът могат да използват Infra. - person eduncan911; 01.04.2009
comment
Единственият проблем, който имам с това, е, че моята книга казва, че инфраструктурата никога не препраща към нищо. UI-›Приложение, домейн и инфра. Приложение-›домейн и инфра. И, Domain-›Infra. Знам, че знам, така или иначе всичко трябва да е насока. - person eduncan911; 02.04.2009
comment
Вярвам, че има проблем с този отговор около Приложния слой е отговорен за инжектирането на правилната инфраструктура в домейна.. Onion архитектурата ни казва, че инфраструктурата дори не трябва да влиза в домейн слоя, не трябва да знае нищо за това, че трябва да изпрати имейл за инстанция. И с това имам предвид, че не трябва да знае, че имейл дори трябва да бъде изпратен, а не само че не знае, че е изпратен имейл. Причината е, че се опитваме да напишем чист основен домейн, който има само основната бизнес логика. Екстра като изпращане на имейл като страничен ефект разводнява домейна. - person Craig; 02.04.2021

Аз съм нов в DDD, така че не се колебайте да коментирате, ако не сте съгласни, тъй като вие съм тук, за да науча.

Лично аз не разбирам защо трябва да препращате към инфраструктурния слой от вашия домейн. Според мен домейнът не трябва да зависи от инфраструктурата. Обектите на домейна трябва да са напълно невежи в коя база данни работят или кой тип сървър за електронна поща се използва за изпращане на имейли. Чрез абстрахиране на домейна от инфраструктурата е по-лесно да се използва повторно; защото домейнът не знае на коя инфраструктура работи.

Това, което правя в моя код, е да препращам към домейн слоя от моя инфраструктурен слой (но не обратното). Репозиториите познават обектите на домейна, защото тяхната роля е да запазят състоянието на домейна. Моите хранилища съдържат моите основни CRUD операции за моите коренни агрегати (get(id), getall(), save(object), delete(object) и се извикват от моите контролери.

Това, което направих в последния си проект (подходът ми не е чисто DDD, но работи доста добре) е, че абстрахирах моите хранилища с интерфейси. Основните агрегати трябваше да бъдат създадени чрез предаване на конкретен тип хранилище:

Основният агрегат трябваше да бъде инстанциран през хранилище чрез използване на метода Get(ID) или Create() на хранилището. Конкретното хранилище, конструиращо обекта, премина само по себе си, така че агрегатът да може да запази неговото състояние и състоянието на неговите дъщерни обекти, но без да знае нищо за конкретната реализация на хранилището. напр.:

public class PostRepository:IPostRepository
{
     ...
    public Post Create()
    {
        Post post=new Post(this);
        dbContext.PostTable.Insert(post);
        return post;
     }
     public  Save(post)
     {
         Post exitingPost=GetPost(post.ID);
         existingPost = post;
         dbContext.SubmitChanges();
     }
}

public class Post
{

     private IPostRepository _repository
     internal  Post(IPostRepository repository)
     {
        _repository = repository;
     }
     ...
    Public Save()
    {
        _repository.Save(this);
     }

}
person Geo    schedule 29.03.2009
comment
Знам накъде отиваш с това. Просто в моята DDD книга се споменава, че хранилищата са в инфраструктурния слой. Но противоречивата информация, която намирам в мрежата, поставя хранилищата в слоя на домейна. - person eduncan911; 30.03.2009
comment
Също така се препоръчва UI-слоят да има достъп до приложението, DOmain и инфраструктурата, приложният слой да има достъп до домейна и инфраструктурата и накрая домейн-слоят да има достъп до инфраструктурата. Това е от книгата DOmain Driven Design Quickly. Следователно причината за това? - person eduncan911; 30.03.2009
comment
Това е трудна информация за определяне. Това, което мисля, че разбрах, е, че интерфейсите за хранилища влизат в слоя на домейна, тъй като те определят шев за домейна. *Имплементациите на хранилищата отиват в инфраструктурния слой. Представете си, че решавате напълно да извлечете домейна си от текущия контекст на приложението и да изградите изцяло нов. Бихте искали интерфейсите на хранилищата, но не непременно имплементациите. - person jlembke; 15.07.2009

Бих ви посъветвал да обмислите Onion архитектура. Много добре пасва на DDD. Идеята е интерфейсите на вашето хранилище да се намират в слой точно извън домейна и да препращат директно към обекти:

IPostRepository.Save(Post post)

Домейнът изобщо не трябва да знае за хранилищата.

Инфраструктурният слой не се споменава от домейн или някой друг и съдържа конкретни реализации на хранилища наред с други неща, свързани с I/O. Общата библиотека с различни помощници се нарича Application Core в този случай и може да бъде използвана от всеки.

person Alexander Abramov    schedule 31.03.2009
comment
погрешно Хранилища на домейни и интерфейс на шлюзове. Инфраструктурният слой ги изпълнява. - person Mik378; 04.11.2017