我设立在我申请洋葱架构和DDD模式的解决方案。
其中一个DDD原则,鼓励域实体只有私人制定者和私人默认的构造函数,以确保您不能处于无效状态创建域实体。
存储库包含关于域实体,这是从/到数据库映射到的数据的操作。我一直在尝试以下两种方法:
这两种方法的工作,但是,与选项2的资料库变得非常简单,因为它们含有少了很多自定义映射代码,并没有反射显然会更高性能的为好。当然,DDD不是以纯粹的方式应用。
前一个决定什么,我会在我的项目中使用,一个问题:是否有任何其他微ORM框架,有可以处理私有构造函数和setter方法,使映射数据库的那种“纯”领域的实体不进行额外支持自定义映射逻辑是什么? (无EF也不NHibernate的,我想要的东西轻量级)。
或其他技术解决方案,以保持“纯”模型实体结合容易库映射方法?
编辑:我实现了解决方案是以下。
首先,构造函数和setter域中实体都是“内部”,这意味着它们不能被消费者域模型的设定。但是,我用“InternalsVisibleTo”允许数据访问层直接访问它们,所以这意味着从数据库非物质化是很容易与短小精悍(无需中级车型)。从应用层,我只能使用域的方法来直接改变域实体,而不是性能。
其次,从我的应用层构建新的域的实体,我说一口流利的建设者,以帮助建筑领域的实体,所以现在我可以构建他们像:
User user = new UserBuilder()
.WithSubjectId("045454857451245")
.WithDisplayName("Bobby Vinton")
.WithLinkedAccount("Facebook", la => la.WithProviderSubjectId("1548787788877").WithEmailAddress("[email protected]"))
.WithLinkedAccount("Microsoft", la => la.WithProviderSubjectId("54546545646").WithEmailAddress("[email protected]"))
当构造器“构建”实体,验证完成后为好,这样你就可以永远处于无效状态创建一个实体。
其中一个DDD原则,鼓励域实体只有私人制定者和私人默认的构造函数,以确保您不能处于无效状态创建域实体。
这是不完全正确。是的,丰富的域模型通常不暴露setter方法,但那是因为他们不需要setter方法。你告诉模型如何在更高的抽象水平做,并允许它来确定自己的数据结构应当如何修改。
同样,也有经常情况下是有意义的公开默认的构造函数:如果你认为一个聚合为一个有限状态机,那么默认的构造函数是一种方法来初始化它的“启动”状态的总和。
所以通常你在以下两种方法之一重建而成:要么你初始化它在默认状态下,然后发送了一堆邮件,或者你使用Factory
模式,如在蓝皮书描述。
这意味着其间的额外的映射,这使得代码更复杂
也许吧,但它也可以确保您的域名代码更少依赖于ORM的魔力。特别是,它意味着你的域逻辑可以在比什么是用来做持久性“容易”的不同的数据结构进行操作。
但它不是免费的 - 你必须在代码中如何获取值出聚合根和回数据库(或进入ORM实体,作为数据库的代理)来形容。
关键是,你不使用小巧玲珑与您的域实体合作,而是你用它来与POCO实体存储库层内。您的仓库方法将通过转换POCO实体(即小巧玲珑的用于数据访问)域实体返回域实体。