标签: bounded-contexts

DDD中两个有界上下文之间的通信

我在域中几乎没有不同的有界上下文.CRUD操作的验证建立在每个有界上下文中.

例如,只有创建它的人是组长,我才能创建一个名为GAME的实体.

在这个例子中我有两个有界上下文(BC).一个是游戏BC,另一个是用户BC.为了解决这个问题,在游戏BC中,我必须在继续创建游戏之前向用户BC进行类似IsGroupLeader()的域服务调用.

我不认为DDD推荐这种类型的通信.我也可以在游戏BC中拥有一个用户实体,但我不想这样,因为同一个用户实体在不同的BC中的不同上下文中的使用方式不同.

我的问题是:

  1. 我是否应该使用域事件,其中游戏BC必须向用户BC发送事件以询问用户状态?使用这种方法,我不会像IsGroupLeader那样进行同步调用,而是进行名为is_group_leader的事件.然后游戏BC必须等待用户BC处理事件并返回状态.只有在用户BC处理事件之后,游戏BC才会创建游戏实体.

  2. CQRS是我问题的解决方案吗?

任何想法都赞赏.

domain-driven-design cqrs domain-events bounded-contexts

26
推荐指数
2
解决办法
1万
查看次数

域驱动设计中有限上下文中的实体

我试图了解实体如何在多个有界上下文中运行.

给予公司员工.在(例如)人力资源上下文中,此人具有姓名,地址,工资参考编号和银行帐户.但在会计方面,所有相关的是工资参考编号和银行账户.

您是否在HR上下文中有Employee实体,SalariedEmployee在Accounting上下文中有Value-Type(例如)?

class Employee
{
    public BankAccount BankAcountDetails { get; set; }
    public string FullName { get; set; }
    public Address ResidentialAddress { get; set; }
    public string SalaryRef { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SalariedEmployee class(??):Employee的值类型

class SalariedEmployee
{
    public SalariedEmployee(string salaryRef, BankAccount bankAcountDetails)
    {
        ...
    }

    public string SalaryRef { get; }
    public BankAccount BankAcountDetails { get; }
}
Run Code Online (Sandbox Code Playgroud)

有界上下文中的HRService是否返回此信息?或者你在两种情况下都使用Employee类?

entity domain-driven-design value-type bounded-contexts

15
推荐指数
2
解决办法
7219
查看次数

如何建模存在于所有有界上下文中并且是应用程序核心部分的实体?

我正在使用DDD原则制作应用程序.在尽可能多地思考一切之后,我就开始制作我的有界背景了.我还没有设置最终结构,但截至目前,我的应用程序将包含以下有界上下文:

  1. 员工管理
  2. 购买
  3. 档案
  4. 报告

我希望它尽可能地可插拔,所以我可以单独开发和维护它们.他们可能会公开WCF或Web API来与它们进行交互.

我将使用Udi Dahans实现一个简单的CQRS模式.我不想一直使用事件源,消息总线等,因为这不是一个高度协作的应用程序(少于1000个用户,他们不太可能编辑相同的小数据集),这将增加了许多不必要的复杂性.

那么问题:

所有BC的员工和部门实体都很常见,如何建模?

部门是组织结构的一部分,因此在员工管理BC中,员工在一个部门工作,他们可以管理一个部门,他们有他们所从事过的部门的历史.

在购买BC商品是从部门购买,并交付给部门.Suplliers与不同部门签订了不同的合同.

在存档中,一些信息将被存档并绑定到一个部门,依此类推.

这同样适用于员工.

如何从有界上下文中保留数据?

它们可以映射到同一个数据库,也可以各自拥有自己的数据库.

到目前为止我已经做了一些想法

如何建模
我应该再建一个名为"公司"或"组织"的BC并在那里管理部门吗?

根据上面引用的Udi Dahans文章,我应该为每个BC制作一个部门实体和一个雇员实体,只需要我所需要的BC字段和行为.这听起来很合理,但后来我正在考虑如何实际使用它,我无法弄明白.我需要访问其他地方管理的部门,但我究竟是如何做到这一点而不是混合我的BC?

如何使用?
假设我通过查询从somwhere获取我的部门列表.在UI中我得到了我想要购买的部门列表.这是该部门的第一次购买,因此采购BC还不了解这个部门......所以购买BC的部门对象将填充从其他BC维护的数据 - 所以我该如何坚持这一点?如果不存在,我需要添加一些信息,如送货地址和发票地址?

在"注册部门UI"中,我应该在所有BC上调用"RegisterDepartment"服务,然后确保这些服务与通过UI(MVC控制器)所做的所有更改同步吗?

与员工一样.我想知道哪个员工进行了购买或在存档中放了一些东西.所以我不知何故在这些BC中也需要一个员工对象,但是从不同的BC管理它们.

持久化
可以通过将不同的employee-objects映射到数据库中的同一个表来解决上面的一些挑战.购买BC和Archive BC不能注册新员工,而是将信息附加到那些在那里的人并将他们绑定到同一数据库中的其他对象.然后数据库会让所有BC仍然生活在同一个世界......

我需要建议,所以我最终不会制作一些以后很难维护的东西.

c# design-patterns domain-driven-design cqrs bounded-contexts

15
推荐指数
2
解决办法
2658
查看次数

如何表示有界的上下文?

我的意思是 - 在物理上,在代码中.组织命名,命名空间,文件夹,程序集,数据库.

有限的上下文应该如何互动?

例如,随意使用经典的电子商务业务领域.

c# domain-driven-design bounded-contexts

13
推荐指数
2
解决办法
2586
查看次数

有界的上下文实现和设计

假设我有两个有界的上下文,即Shipping ContextBilling Context.这些背景中的每一个都需要了解客户.

在数据级别,客户由CustomerTbl数据库中的表表示.该表包含描述客户的所有必要列.

CustomerTbl(简化)中的列:

  • Name
  • PhysicalAddress
  • PaymentMethod

装运情境关注的是NamePhysicalAddress计费上下文关注的是NamePaymentMethod.

装运背景中,我已对聚合建模Recipient:

  • Recipient现在有属性/值对的对象NamePhysicalAddress

结算上下文中,我已对聚合建模Payer:

  • Payer具有属性/值对的对象NamePaymentMethod

两者RecipientPayer聚合都完全由上下文边界分隔.他们也有自己的存储库.

问题:

  1. 是否可以使用相同的"数据库表"来拥有多个聚合(假设它们位于不同的有界上下文中)?

  2. 在更多有限的背景下可能需要客户数据.这不意味着每个有界上下文的许多聚合,存储库和工厂实现吗?代码中会有一定程度的冗余.这不会影响可维护性吗?

  3. 跨聚合共享属性是否可以接受?一个例子是客户Name财产.这也意味着冗余的验证码?

domain-driven-design aggregateroot repository-pattern onion-architecture bounded-contexts

12
推荐指数
1
解决办法
1822
查看次数

有界上下文是一个完整的应用程序?

我一直在阅读DDD和有限的背景,我想我的想法是错的.起初,我喜欢子域和有界上下文的想法,我理解它是这样的:有一个软件可以开发,但是同时攻击所有的东西太多了,所以我们将它分解成逻辑部分并立即开发每个部分.我们解决的另一个问题是无处不在的语言含糊不清.

这导致我将有界上下文视为基本上只是文件夹,其中我对与应用程序的某个特定部分相关的代码进行分组和绑定.这段代码我认为是由像这样的东西组成的

  • 有界上下文的域模型,包括存储库和服务的抽象
  • 有限上下文的基础结构层,存储库的实现等

当然,作为域模型和基础设施在有限的上下文中正确地分开.

然而,进一步阅读,似乎每个有界的上下文都是它自己的整个应用程序.有时,似乎每个有界上下文都有自己的应用层.

这让我感到困惑,因为有时候我不想最终开发出大量的应用程序,我只想开发一个应用程序.应用程序的有界上下文划分应该构建一个应用程序,而不是要集成的应用程序.

我似乎在这个问题中@MikeSW说OP提出的两种方法都是有效的.我问的是关于第三种结构:

<bc 1>
 |_ domain
 |_ infrastructure
<bc 2>
 |_ domain
 |_ infrastructure
|_ application
|_ presentation
Run Code Online (Sandbox Code Playgroud)

至少对于所有应用程序,我觉得这更有意义.我想要一个应用程序,而不是几个带有多个演示文稿的应用程序,但我仍然希望能够打破"限制无处不在的语言"等领域并从中受益.

那么,有限的上下文是完整的应用吗?或者可以使用有限的上下文,就像我理解并感觉更有用一样?我的方法有什么问题吗?

domain-driven-design bounded-contexts

12
推荐指数
2
解决办法
1367
查看次数

DDD - 如何设计不同有界上下文之间的关联

我已经设置了一个用ORM填充的域项目.域包含不同的聚合,每个聚合都有自己的根对象.我的问题是如何处理跨越聚合边界的属性?

  • 这些属性是否应该忽略边界,以便有界上下文A中的域对象具有对上下文B中对象的引用?
  • 或者,如果没有从上下文A到B的直接链接,并且上下文A中的对象是否具有"int ContextBId"属性,该属性可用于通过B聚合根从B获取域对象?
  • 要么 ...

示例:
上下文A =用户
上下文B =游戏

Users上下文中有一个对象UserOwnedGames.此对象具有一个属性User,该属性是对同一Users上下文中的对象的引用.该对象还具有一个属性,Game该属性显然不在用户中,而是在Games上下文中.

怎么会(或应该?)这种关系是什么样的?它在数据库中很清楚(即2个外键),但代码应该是什么样的?

domain-driven-design aggregateroot bounded-contexts

9
推荐指数
1
解决办法
3707
查看次数

实现有界上下文到基于实体框架的基础设施

我创建了一个基础设施,这是我们新的内部网络项目,并试图遵循几乎所有最佳实践.另外,我想提一下,这是我第一次从零创建架构.

目前,我的基础设施的第一个版本已经准备好并且运行良好 但我想在下一个版本实现有界上下文结构.

我试着解释下面的现状.

DbCore:负责数据操作.实体框架5代码首先使用.只有一个DbContext类,并且在其中定义了所有DbSet.另外,GenericRepository模式和Unit of Work模式基于以下接口实现.

IGenericRepository

public interface IGenericRepository<TEntity>
     where TEntity : class {
        void Delete(object id);
        void Delete(TEntity entityToDelete);
        System.Collections.Generic.IEnumerable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null, Func<System.Linq.IQueryable<TEntity>, System.Linq.IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
        System.Collections.Generic.IEnumerable<TEntity> GetAll();
        TEntity GetByID(object id);
        System.Collections.Generic.IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters);
        void Insert(TEntity entity);
        void Update(TEntity entityToUpdate);
    }
Run Code Online (Sandbox Code Playgroud)

IUnitOfWork

 public interface IUnitOfWork {
        void Dispose();
        IGenericRepository<Test> TestRepository {
            get;
        }
        IGenericRepository<Log> LogRepository {
            get;
        }
        void Save();
    }
Run Code Online (Sandbox Code Playgroud)

模型: DbCore和实体框架域的负责存储实体模型 …

domain-driven-design unit-of-work repository-pattern bounded-contexts entity-framework-5

8
推荐指数
1
解决办法
2635
查看次数

事件源的关系数据库模式

我试图将域事件存储在postgres数据库中.我在很多方面都不确定,我不想在以后重新设计这个结构,所以我正在寻找具有事件采购经验的人的指导.我目前有下表:

domain events
    version - or event id, integer sequence, helps to maintain order by replays
    type - event type, probably classname with namespace
    aggregate - aggregate id, probably random string for each aggregate
    timestamp - when the event occured
    promoter - the promoter of the event, probably user id
    details - json encoded data about the properties
Run Code Online (Sandbox Code Playgroud)

我不确定的是什么:

  1. 我应该存储域事件的启动器吗?
    它可能有助于找到安全漏洞导致的受损帐户,但我不知道如何通过CRONjob存储什么.
  2. 我应该以什么格式存储事件类型?
    我应该添加一个包含事件类型的表,还是类名呢?
    我应该添加活动组吗?
  3. 我对有界上下文的定义感到困惑.据我所知,每个聚合都可以有多个有界上下文,因此我可以在多个模块中使用单个聚合的不同方面.这听起来不错,因为例如帐户可能与许多事情有关,包括身份验证,授权,用户配置文件,用户帖子,用户合同等......
    我不确定,域事件可以有多个有界上下文,或者只是一个,所以我也应该存储事件上下文?(对于我想重放与单个上下文相关的事件的情况)
    如何在单个聚合类中实现这么多属性,我应该使用某种组合吗?

postgresql domain-driven-design cqrs event-sourcing bounded-contexts

7
推荐指数
1
解决办法
4030
查看次数

有界上下文的大小

我已经开始学习DDD的原理了,我现在正试图掌握有界上下文的概念.特别是,你如何决定它有多大(或小)?是的,我知道,尽可能小,必要的大(根据Vaughn Vernon).

假设我要为博客建模.然后我可以说有3个有界的背景:1)Front Page(以最新的文章为特色,没有显示评论)2)讨论(包括评论的单篇文章)3)Article Composer(我撰写文章的地方).

然而,这感觉不对(无处不在的语言对所有人来说都是一样的),似乎我是从前端角度来看,我仍然在考虑视图模型或其他东西.

有谁能请我指出正确的方向?

domain-driven-design bounded-contexts

6
推荐指数
1
解决办法
890
查看次数