是否可以在不改变作为框架一部分的DDD模型的情况下使用NHibernate

W3M*_*Max 15 nhibernate frameworks domain-driven-design fluent-nhibernate

我挖掘了很多关于DDD方法(无处不在的语言,聚合,存储库等)的东西,我认为,与我经常阅读的内容相反,实体应该有行为而不是不可知.我看到的所有示例都倾向于使用虚拟自动属性空构造函数(受保护或最差,公共)呈现实体,就是这样.我认为这种对象更像是DTO然后是实体.

我正在使用其特定的API 创建框架,我不想被绑定到ORM.所以我首先构建了域(不考虑持久性),现在我想使用NHibernate作为持久性工具,所以我在当前的解决方案中添加了一个新项目,以帮助确保我的模型不会被改变以支持NHibernate.该项目应该是我域内的抽象存储库的实现.现在困难出现了.

因为这是我第一次使用NHibernate(我也尝试Fluent Nhibernate,但似乎更加限制)我想知道:

  1. 是否可以在不改变作为框架一部分的DDD模型的情况下使用NHibernate
  2. NHibernate按预期和有效工作所需的东西(约束)(虚拟属性,空构造函数等)我认为这个列表对很多开始学习NHibernate的人都有帮助.

请记住,我正在构建一个框架,因此开放/封闭原则对我来说非常重要.

PS:对不起,如果我的英语不好,我来自蒙特利尔,我说法语.

编辑1:这是我现在对NHibernate的一个问题 - 如何使用Nhibernate(和Fluent NHibernate)映射Type

yfe*_*lum 9

  • 对于NHibernate:
    • 所有映射的类都需要一个默认(无参数)构造函数.默认构造函数不必是公共的(它可以是私有的,因此它不是API的一部分),但它必须存在.这是因为NHibernate必须能够创建映射类的实例而不传递任何参数.(有解决方法,但不要这样做.)
    • 必须标记所有需要延迟加载的映射属性virtual.这包括所有引用属性和所有集合属性.这是因为NHibernate必须能够生成派生映射类并覆盖映射属性的代理类.
    • 所有映射的集合属性都应使用接口作为属性类型.例如,使用IList<T>而不是List<T>.这是因为.NET Framework中的集合类型往往是密封的,并且NHibernate必须能够用它自己的集合类型实例替换集合类型的默认实例,并且NHibernate有自己的集合类型的内部实现.
    • 对于NHibernate的,喜欢Iesi.Collections.Generic.ISet<T>System.Collections.Generic.IList<T>,除非你确信你想要的东西实际上是一个列表,而不是一.这需要熟悉列表集合的理论定义以及域模型所需的内容.当您知道元素必须按特定顺序排列时,请使用列表.

还要注意,交换对象关系映射框架通常并不容易,并且在很多情况下,当你有一些超出简单的域模型的东西时,它是不可能的.


Jef*_*nal 4

对您问题的简短回答是,这是不可能的,但如果不需要延迟加载,则所需的更改是微不足道的。

无论如何,您都将向尚未具有默认构造函数的类添加默认构造函数。如果您愿意放弃延迟加载,那么这些默认构造函数可以是私有的,并且您无需对域模型进行任何其他更改即可使用 NHibernate。

这非常接近于持续性的无知。

话虽如此,如果您想要延迟加载,则需要进行一些更改(在该问题的其他答案中概述),以便 NHibernate 可以创建聚合实体的代理。我个人仍在尝试确定延迟加载是否是 DDD 的一项支持技术,或者它是否是一种过早的优化,需要对我的 POCO 进行太多侵入性更改。我倾向于前者,尽管我真的希望 NHibernate 可以配置为使用特定的构造函数。

您还可以看看 Davy Brion 的博客(我特别喜欢Implementing A Value Object With NHibernate),如果您对领域驱动设计和避免贫乏的领域模型感兴趣,那么该博客确实很有启发性。