Tag: 域驱动设计

如何选择DDD Aggregate?

在第4章(第一个草图) 中使用C#中的示例应用域驱动设计 第4章(第一个草图) 。 并发冲突检测很重要我不明白为什么作者选择了这个聚合。客户有他自己的聚合和订单有他的自己的聚合。 我认为客户应该参考他的订单。 订单只与客户有身份。 我没有看到一个情况是通过他的id从数据库获得订单。 但是如果我应用这个逻辑,那么在我的域模型中,我几乎没有包含所有实体和值对象的复杂聚合。 我不想要这个。 从数据库获取客户时,它不会直接加载他的订单(延迟加载)。 所以这不是一个论点。 如果客户在不同的场景中使用,那么最好清除客户的参考仅在一个场景中有用。 我猜这是为订单汇总并对其订单进行“间接参考”的一个原因。 那么选择聚合的真正原因是什么? 我有另一个误解。 订单有更多OrderLine。 OrderLine有一个产品。 为什么OrderLine允许在聚合顺序之外引用对象(Product)?

在CQRS中注册EventHandler

我正在尝试使用CQRS和DDD模拟购买域,我知道我在域中引发事件但我不知道在我使用命令时在哪里注册它们。 应该在命令处理程序中注册事件处理程序吗? 或者我误解了一些东西。 这是我的过程,你可以帮助建模吗? 最终确定采购订单命令,比命令处理程序最终确定订单(从存储库获取订单,更改其状态并保存回db),订单最终事件发生在域模型中,而不是事件处理程序使用id及其行项找到此订单,查找它供应商联系信息(可能是电子邮件甚至是外部服务)并通知他新的采购订单。 我的命令和命令处理程序在应用程序层中(事件处理程序也应该在这里?)。 域层中的域模型,事件和IRepositories。 基础架构层中的存储库实现。 域模型(跳过大多数属性): public class PurchaseOrder { public PurchaseOrder(int purchaseOrderID, int supplierID, bool isOrderFinalized) { PurchaseOrderID = purchaseOrderID; SupplierID = supplierID; IsOrderFinalized = isOrderFinalized; } public int PurchaseOrderID { get; private set; } public int SupplierID { get; private set; } public bool IsOrderFinalized { get; private set; } […]

使用DDD有界上下文的实体配置管理

我正在尝试实现此处概述的多个DDD有界上下文。 这是一个示例上下文: 我有一个实体类型配置文件,每个实体都有适当的FluentAPI映射(使用EF工具进行反向工程)。 这些配置文件还包括关系配置。 例如:UserMap.cs // Relationships this.HasOptional(t => t.SecurityProfile) .WithMany(t => t.Users) .HasForeignKey(t => t.SecurityProfileCode); SecurityProfile和DomainPermission不是DbSets中的DbSets 。 由于User和Module上的导航属性,它们会自动进入模型。 这导致我的第一个问题。 将User (或任何其他实体)添加到任何其他上下文时,我必须记住执行以下两项操作之一: 还要将配置添加到SecurityProfile的模型构建器(以及实体上的每个其他关系) 以某种方式明确地从模型中排除SecurityProfile 。 这开始变成一个维护噩梦。 我很满意明确地“修剪”实体图,如上面第2点所述。 但是,当实体配置文件中已经定义了关系时, Ignore()实体似乎不可能。 尝试使用modelBuilder.Ignore(); 对于上面的上下文OnModelCreating在ConfigureAssociations()给出以下错误: System.InvalidOperationException:导航属性“SecurityProfile”不是“User”类型的声明属性。 validation它是否未从模型中明确排除,并且它是有效的导航属性。 我能想到的唯一解决方案是inheritance基本配置类并覆盖每个上下文中的关系配置。 考虑到我们最终可能会有30-40个单独的背景,这也可能成为维护的噩梦。 或者,我可以为每个上下文设置非常具体的实体模型,但这又会导致实体类爆炸以及重复配置中的潜在维护问题。 在实施有界上下文时,如何才能最好地管理和维护实体及其实体配置?

具有Nhibernate设计问题的域模型

我正试图开始使用“DDD with C#”世界。 我使用NHibernate作为我的ORM工具,因此尝试开发PI(Persistence Ignorance)模型。 但是,在我的一些实体(表示为POCOS)中,我在我的属性的setter中有业务规则。 例如,我有一个“User”实体,它有一个标志,指示此用户是否被阻止,当此标志为true时,必须自动填充当前日期的第二个字段“Block Date”。 一切看起来都非常清晰和简单,但问题出现在我恢复已经持久存储在数据库中的用户,即使被阻止的用户将其“阻止日期”更新到当前日期,根据这个逻辑。 最初我想到了第二个标志“isLoaded”,它表明NHibernate正在对象进行水合,然后这个逻辑不会被启动,但这看起来不像PI。 有关如何改善这一点的任何建议?

值对象应该保持对实体的引用吗?

值对象是否应该在DDD方法中引用实体? 编辑 @Dmitry: 这可能是我的情况。 在这里,我附上了类图,其中Account持有对IInvoiceable项的集合的IInvoiceable 。 我认为Tenant是实体,但它只拥有1个账户,我不认为Account需要身份。 它是Tenant一部分。 或者我应该将其视为实体? 对我来说它没有意义。

DDD会导致很多添加/更改方法和构造函数重载吗?

我上课了: public class Person { public string FirstName { get; private set; } public string LastName { get; private set; } public string Email { get; private set; } public string Telephone { get; private set; } public Address Address { get; private set; } public Person(string firstName, string lastName) { //do null-checks FirstName = […]

DDD和entity framework类

我已经阅读了很多关于DDD的文章并且理解,我应该在基础结构级别使用我的域模型类,因此,我应该使用与Entity Framework基础结构相同的类并使用它们来生成表(代码优先方法)等。但是我的域模型可以与Relational DB模型完全不同。 为什么我不能创建另一个模型,基础架构模型,创建关系数据库模型,不要将域模型与EF类混合?

域驱动设计API问题

我是DDD的新手,我正在开展我的第一个项目,即在线高尔夫郊游注册过程。 我的要求非常简单。 用户注册外出,可以选择添加四人组。 他们还可以赞助一个带有消息和其他一些东西的漏洞,但我想首先勾勒出我们最糟糕的东西。 所以,我的第一个虽然我的聚合包含一个注册实体,四个值对象(包含一个团队名称和4个玩家值对象)。 在设计api时,我正在考虑以下伪代码: Registration reg = new Registration(); Foursome foursome = reg.CreateFoursome(“My Team”); foursome.Player1.Assign(“John Doe”, 5, ShirtSize.XL); reg.Register(); 我的问题是,聚合的一个内部组件正在暴露给客户端代码,所以我是否为问题打开了自己? 这种简单设计或替代api的任何缺陷? 任何帮助都会很棒,因为我现在处于分析瘫痪的状态! 谢谢

在Fluent NHibernate中处理与值类型的一对多关系

我正在努力将应用程序迁移到NHibernate,我正在使用Fluent NHibernate。 我遇到了一个将值类型集合映射到聚合根的问题。 我有一个PhoneNumber值类型,它具有一些属性 – Number , NumberType和Description 。 我的域中有许多对象都有电话号码集合。 在数据库(SQL 2008)中,这些值保存在不同的表中。 所以我可能有Customers和CustomerPhoneNumbers以及Vendors和VendorPhoneNumbers 。 电话号码表是相同的,除了将它们与父母相关联的外键。 问题是我想使用一个简单的PhoneNumber值类型,而不必创建具有将它们与其父类型相关联的属性的CustomerPhoneNumber和VendorPhoneNumber类型,我不知道如何在NHibernate中实现它。 这是可能的还是我需要更改我的域对象以更紧密地匹配底层数据库架构? 更新:更多信息 看起来我甚至无法将基本地图用于检索。 这是我所拥有的简化示例: public class CustomerMap : ClassMap { public CustomerMap() { Table(“Customers”); Id(x => x.Id); Map(x => x.Name); Component(x => x.Address); HasMany(x => x.PhoneNumbers) .KeyColumn(“CustomerId”) .Cascade.All() .Table(“CustomerPhoneNumbers”); } } public class PhoneNumberMap : ClassMap { public PhoneNumberMap() […]

DDD域模型复杂validation

我正在使用域驱动设计原则重写我的ASP.NET MVC应用程序。 我正在尝试validation我的用户实体。 到目前为止,我能够validation基本规则(例如用户名和密码是非null /空格字符串)。 但是其中一条规则,我需要确保用户名是唯一的。 但是我需要访问数据库才能执行此操作,这意味着我必须将IUserRepository注入我的User实体中。 public class User { private readonly IUserRepository _userRepository; public User(IUserRepository repo) { _userRepository = repo; } public override void Validate() { //Basic validation code if (string.IsNullOrEmpty(Username)) throw new ValidationException(“Username can not be a null or whitespace characters”); if (string.IsNullOrEmpty(Password)) throw new ValidationException(“Password can not be a null or […]