我们的每个边界上下文都有一个事件消息处理器,它从上下文间总线提取消息,并通过内存总线(Reactive Extensions,或https://github.com/flq/MemBus)在本地调度。
在DDD书籍中,我读到它讨论了在项目中的模块中放置消息,例如mycompany.accounts.infrastructure.messages
和mycompany.ordering.infrastructure.messages
。
对我来说,多重上下文的问题是,引用这些消息会导致循环引用。
如何组织不同的有界上下文消息传递契约:
-
是否每个有界上下文都有一个单独的项目,包含该上下文的所有可能的消息,以便其他有界上下文可以引用?
-
还是为所有将通过上下文间总线的消息提供单独的共享库更好?
我解决了类似的问题,为每个有界上下文构建(至少)两个程序集:
- 一个用于合约(事件、异常、共享标识符等)
- 一个用于实体的实现。
这样,不同的有界上下文实现可以引用相同的契约,而不需要任何循环。
编辑
至于命名约定,我通常以有界上下文的"约定名称"为程序集命名,例如
- BankName。合同财务咨询
- BankName.FinancialAdvisory。实现的POCO
- BankName.FinancialAdvisory。ORMOrOtherTechnologicalCouplingName当我需要专门化一些类以便在特定的技术环境中使用它们时。
然而,在POCO程序集中,根名称空间与契约的名称空间相同(例如bankname . financiicaladvisory):这是因为POCO在没有任何技术关注的情况下用代码表达业务规则,具有与契约相同的开发生命周期。相反,包含技术专门化的程序集使用的根命名空间等于程序集名称(例如BankName.FinancialAdvisory.ORMOrOtherTechnologicalCouplingName)。
尽管如此,与域相关的所有程序集共享相同的名称空间结构:例如,如果名称空间"Funds"存在于BankName下。财务顾问,它也存在于POCO和ORMOrOtherTechnologicalCouplingName(如果它包含任何类,当然)。