DDD, BoundedContexts, доменные события и транзакции - PullRequest
1 голос
/ 31 мая 2011

В настоящее время я занимаюсь созданием Испытания концепции для системы администрирования продукта / партии, основанной на принципах DDD.Одно из требований заключается в том, что данные о стороне (клиент, посредник) будут храниться в CRM в Интернете, а данные о продукте будут храниться в базе данных SQL (см. Ниже).

CRM-система (через Интернет)
Клиент (содержит имя, адрес, адрес электронной почты, контактные данные и т. Д.)
Торговый посредник (содержит имя, адрес, активный статус)

Система продуктов(В помещении)
BaseProduct (определяет ванильный продукт)
ResellerProduct (определяет настройку базового продукта, который будет продаваться посредником) CustomerProduct (определяет продукт, который клиент зарегистрировал).

Я проводил много исследований различных подходов к тому, как я могу реализовать решение, но изо всех сил пытаюсь понять все концепции и то, как они применимы к моей проблеме.

Iначалось с разделения областей на 2 различных ограниченных контекста, Party и Product.Я определил доменные модели для каждого из этих контекстов, и в тех случаях, когда сущности ссылались на концепции в другой модели, я оставил их как простые идентификаторы Guid (т. Е. CustomerProduct в домене продукта будет иметь значение CustomerRef соответствующего Guid).

Затем я реализовал реализацию инфраструктуры Party, которая использовала вызовы API для веб-CRM, и реализацию инфраструктуры Product, которая использовала NHibernate.Для каждого из них я реализовал UnitOfWork, чтобы я мог контролировать процесс транзакции в каждом контексте.Прикладному уровню необходимо внедрить два контекста во время выполнения и использовать их.

Например:

  • ApplicationService.RegisterNewProduct (customerId, ProductId)
  • Запустить транзакциюкаждой единицы работы (PartyUnitOfWork.Begin (), ProductUnitOfWork.Begin ())
  • Используйте репозитории для каждого контекста, чтобы найти соответствующие доменные объекты (Party.Customer.Find (Id), Product.ResellerProduct.Найти (Id))
  • Выполнить логику, чтобы определить, имеет ли клиент право, продукт действителен и т. Д.
  • Создайте новый CustomerProduct и сохраните в продукте. System
  • Фиксируйте каждый контекстUnitOfWork

Затем я начал исследовать ограниченные контексты немного дальше и думал о рефакторинге приложения, чтобы каждый контекст имел ограниченное представление концепций из другого, но только для конкретного контекста.то есть в контексте Продукта у меня была бы сущность клиента, которая имела бы Id, Имя и активный статус, но, возможно, не имела предпочтений для контактов и т. д. Затем я бы использовала DomainEvents для координации действий между различными системами, чтобы поддерживать свои данные в актуальном состоянии (т.е. еслиВ системе CRM был создан новый клиент, и система Product будет инициировать и обрабатывать событие для обновления представления клиента).Поэтому приведенный выше пример изменится, поэтому будет использоваться только контекст Product.

Чтобы еще больше запутать ситуацию, скажем, что вызов RegisterNewProduct также создал нового Customer, я бы создал клиента в системе Product и поднял бы 'Событие NewCustomer, которое будет обрабатываться партийной системой?

Мне было бы интересно собрать комментарии людей по поводу этих идей?

1 Ответ

1 голос
/ 02 июня 2011

Помимо моего комментария / вопроса, есть фундаментальная проблема с подходом UnitOfWork, который вы описали.Вы столкнетесь с целым классом проблем с одним из совершенных подразделений, а один потерпел неудачу.В итоге вы получите распределенную транзакцию, охватывающую два контекста.

Лучший (субъективно) подход к ограниченным контекстам, если вам действительно нужно иметь более одного, - это иметь асинхронную, основанную на сообщениях связь между ними.Вы выполняете команду для агрегата в одном контексте и в той же транзакции, что и сохранение изменений в БД, публикуете (например, через NServiceBus или MassTransit) сообщение (событие) о том, что что-то произошло.Другой контекст получает сообщение / событие и реагирует.

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

Имеет ли это какой-то смысл?

...