привет, я раньше не был в вашей ситуации, но я занимаюсь проектированием доменов, которые взаимодействуют с другими подсистемами. У меня нет полной картины, но кажется, что сущность клиента более изолирована от других, CustomerProduct и Product. Итак, правильно ли я предполагаю, что вы представите модель в общем графическом интерфейсе, но это будет только отдельный источник данных?
Во-первых, вы можете решить эту проблему разными способами, а также спросить себя о нефункциональных требованиях, таких как обслуживание, время безотказной работы и поддержка. Будут ли обе системы всегда работать одновременно, или случится так, что вы отключите систему. Подсказка, которую я ищу, - это синхронизация или асинхронность (организация очереди сообщений?) С подсистемами. Этого можно добиться с помощью NServiceBus.
Но чтобы сосредоточиться на своем Домене, вы должны сделать так, чтобы Домен выглядел так, как будто у него есть только одна модель. Это можно сделать разными способами:
1) Пусть ваш ICustomerRepository (интерфейсный контракт, который действует как работа с коллекцией объектов) будет реализован репозиторием, связанным с инфраструктурой, который использует вашу веб-службу в вашей подсистеме. Подсказка состоит в том, что вы должны использовать GUID в качестве ключей, чтобы возникали ключевые конфигурации. Такой подход не позволит вам иметь какие-либо отношения / ассоциации с клиентом из других ваших организаций. Они будут, но только через репозиторий (это решение, которое Джимми Нильссон использует в своей книге (http://jimmynilsson.com/blog/), чтобы не затягивать модель множеством двунаправленных отношений).
2) Зависит от того, как ваши варианты использования будут нацелены / использовать модель, но вы можете создать уровень обслуживания для всего приложения, который находится в одном физическом месте, но использует CustomerService, CustomerProcuctService и ProductService. Чтобы предотвратить утечку логики домена на уровень приложения, некоторая координация между этими объектами может быть инкапсулирована в обработчики событий домена, которые координируют некоторые события между различными службами.
3) вы также можете создать класс CustomerAdapter, который имеет в качестве ключа другие подсистемы CustomerGUID (он не может генерировать ключи, поскольку веб-служба клиента контролирует это). Но вы можете отобразить его в Nhibernate и установить связь между CustomerProduct и CustomerAdapter. Но когда вы отображаете CustomerAdapter, вы загружаете только GUID. Затем убедитесь, что у вас есть ICustomerAdapterService, введенный в свойство с помощью Spring.Net Windsor или какого-либо другого инструмента DI. Тогда вы не должны отображать свойства (например, имя клиента, адрес и т. Д.) Для customerAdapter в Nhibernate. Но когда вы получаете / читаете Adress от CustomerAdapter, он получает его от ICustomerAdapterService и также устанавливает все другие значения. Это не рекомендуемое решение, так как оно нарушит некоторые правила DDD, например отсутствие служб в модели предметной области. Но если вы посмотрите на это с этой точки зрения: на самом деле это можно считать доменной службой, поскольку она решает проблемы в вашем распределенном домене. Однако он включает в себя вещи, связанные с инфраструктурой, такие как реализация службы WCF, и, следовательно, реализация службы должна быть на другом уровне / сборке инфраструктуры.
Наиболее простым является решение 2 Если вы можете справиться с тем фактом, что доступ к объекту клиента будет осуществляться только службой на уровне приложения. Однако этот служебный уровень приложения может быть хорошим антикоррупционным слоем между двумя подсистемами. Вероятно, есть причина, по которой сегодня у вас две подсистемы. Но пример потока взаимодействия (без детального знания того, каков ваш домен):
- GUI вызывает метод Application Service CustomerProductService BuyNewProduct (CustomerDTO customer, ProductDTO newProduct)
- CustomerProductService имеет ICustomerProductRepository и IProductRepository, введенные в конструктор. Он также будет иметь инфраструктуру Service ICustomerFacadeService (измените имя сейчас :-)), которая вводится в Property CustomerFacadeService. Создание этой службы выполняется фабрикой, у которой есть два метода создания: Create () и CreateExtendendedWithCustomerService (). Последний также будет внедрять CustomerServiceFacade
- Метод BuyNewProduct (...) теперь соберет CustomerDTO и использует CustomerGUID для загрузки Customer из CustomerFacadeService, который вызовет веб-службу в другой подсистеме.
- Загруженный клиент гарантирует, что он действительно существует, но теперь мы загружаем продукт с помощью IProductRepository.
- Со значением CustomerGUID и Product Entity мы создаем новую сущность CustomerProduct (которая на самом деле является просто классом сопоставления между продуктами и GUID клиента) и сохраняем ее через ICustomerProductRepository.
- Теперь вы можете позвонить в другую инфраструктурную службу, чтобы отправить электронное письмо вашему клиенту, который будет уведомлен о том, что у него есть доступ к новому продукту. Или вы можете создать события домена в сущности CustomerProduct, которая делегирует это уведомление обработчику событий (на уровне службы приложения), который имеет IEmailService, введенный в ctor. Затем вы инкапсулируете знания предметной области об отправке уведомлений, когда вы подключаете нового клиента к продукту.
Надеюсь, это поможет вам смоделировать вашу область с меньшими усилиями. Потому что делать DDD больно. Требуется много обсуждений с коллегами, экспертами в предметной области и самим собой перед зеркалом :) Это правильный путь? Посмотрите на DDDsample.net события домена или найдите Udi Dahan и события домена.
Пишу здесь ответ, побольше места:
Что касается CustomerAdadpter, также называемого CustomerFacadeService в примере потока взаимодействия, вот мое мнение: как реализовать, зависит от вашего приложения. Будет ли большинство пользователей вызывать основную систему, вызывая вашу «облачную подсистему», которая будет иметь хорошее время безотказной работы: - Тогда вам, возможно, не понадобится очередь, и у вас будет служба WCF в облаке. Ваш CustomerFacadeService будет сервисной оболочкой, которая просто предоставляет метод, который нужен вашему уровню приложения, а также собирает все необходимые объекты DTO. Если ваша облачная система также будет обращаться к вашей основной системе, вам необходимо предоставить некоторые из ваших методов как службу. ЗАТЕМ у вас есть возможность предоставить конечную точку NServiceBus как службу WCF. Это дает вам возможность отключить основную систему без потери информации. Но всегда есть много "но" ... Вам, конечно, нужно иметь службу WCF на другом компьютере, если ваши инфра-технические ребята хотят установить исправления / перезагрузить веб-сервер основной системы. Если у вас есть клиент, ожидающий ответа, в то время как основная система не работает, как долго они будут ждать? Думаю, не слишком долго. Итак, один сценарий, который я вижу в этом, заключается в том, что у вас есть пакеты / отчеты, которые необходимо выполнить, и если одна часть системы не работает, отчетность будет продолжена, когда она снова заработает.
Вот несколько примеров NServiceBus, представленного как служба WCF. Но у меня нет опыта в этом, я просто знаю, что «это можно сделать». http://docs.particular.net/nservicebus/architecture/nservicebus-and-wcf
person
Magnus Backeus
schedule
07.04.2011