我正试图为我最常见的开发场景编写可重用组件:
我制作了一个通用的表示层来表示域对象和要封装在域对象中的数据对象(dc可序列化)。我还有一些domainstate/上下文,在这里我可以引用所有的domainobject实例。其思想是,域对象具有特殊的集合,这些集合在第一次按需访问时从数据源填充。我认为这并不完全是"DDD",但它似乎有效。。。
不管怎样,现在我只停留在数据上下文和数据源部分。我一直在思考如何存储数据以及如何与数据源交互;zip文件、sqlserver、sql-lite文件、实体框架、nhibernate、linqtosql、mongodb等中的xml,我无法决定使用什么。我似乎需要抽象掉数据源和数据上下文,并决定在每个应用程序中使用什么。重要的是,我没有在特定的框架上嵌入任何硬依赖关系。
抽象掉数据上下文和数据源,并让它在各种现有框架中都能很好地工作,这现实吗?我想错了吗?这是一条死胡同吗?
我所想要和需要的(我想)就是我的domainstate能够查询与某些标准匹配的对象的数据上下文。我不确定它是否应该能够处理整个对象图或仅处理单个数据对象,甚至不能处理具体类型,而只能处理一些通用对象,或者是否应该为每个请求克隆它们。当我开始思考这个问题时,我感到非常困惑。。。
Gahhh
更新:
我将DataContext/DatabaseContext(例如EntityFramework)视为一个模块/层,用于将对象缓存在内存中,执行查询,从任何数据源获取和存储数据,并将类型化的对象返回给消费者。这是对的吗?
Repository模式(DDD)和我的DataContext有什么区别?
更新2:
基本上,这是我的模型(好还是坏?):
DataSource->DataContext/DataObject->DomainState/DomainObject->Presenter
我似乎需要抽象掉数据源和数据上下文,并决定在每个应用程序中使用什么。重要的是,我没有在特定的框架上嵌入任何硬依赖项
这就是Repository模式。
Repository模式(DDD)和我的DataContext有什么区别?
存储库是一种提取与存储访问相关的所有内容的方法。它旨在满足应用程序的需求,并接收/发回应用程序其他部分已知的对象。DataContext是EF的实现细节,EF本身就是存储库的实现细节。
存储库具有双重用途
-
允许您通过只公开一个接口来更改存储数据的方式(更改数据库、使用xml文件等)。
-
它将您从以数据库为中心的方法中解放出来,让您专注于领域。这一点非常重要,因为每次你首先开始设计一个带有数据库模式的应用程序时,你不可避免地会尝试将应用程序的其余部分放入其中,这样你就会有一个模仿数据库模式的贫血域。
DataSource->DataContext/DataObject->DomainState/DomainObject->Presenter
在任何应用程序中,基本上都有查询(读取)和更新(写入)。在99%的情况下,域仅适用于写入,因为读取没有业务规则(没有行为),您只需要选择要显示的相关数据。
所以对于写作,我建议使用这种流
ViewModel(输入)->域处理(实体、服务等)->域存储库
根据应用程序的不同,您可以通过多种方式从视图模型获取域实体。如果域非常简单,那么您几乎不需要域,视图模型将是在许多情况下与数据库模式相同的域。
用于读取
查询存储库->ViewModel(Presenter)
当然,控制器通常调用查询存储库,它可能会根据从repo接收的数据组装所需的视图模型(在简单的情况下,repo返回的正是视图模型)。
也许您可以发布一些代码示例?很难确切理解你想做什么,但我会尽力回答你的一些问题和评论。
"这个想法是,域对象有特殊的集合,当它们第一次被访问时,这些集合会根据需要从数据源中填充。我认为这并不完全是"DDD",但它似乎有效…"
这与懒惰加载有何不同?为什么你需要一个特殊类型的收藏品?这与DDD有何关联?
抽象掉数据上下文和数据源,并让它在各种现有框架中都能很好地工作,这现实吗?我想错了吗?这是一条死胡同吗?
不,它不是(这是一条死胡同)。你可以很容易地创建一个没有参考你的持久性技术的域模型,但你仍然需要思考你选择的orm映射器的约束,例如EF不支持enums,nhibernate支持。此外,你从推广中得到了什么?一旦你选择了一个映射器,你就永远不会切换它,即使你切换了,如果你的解决方案的其余部分都很好,你也应该不会有什么问题(不要把你的ISession/DbContext/到处都是,等等)。
"存储库模式(DDD)和我的DataContext有什么区别?"
例如,当你说"我的DataContext"时,如果你指的是EF DbContext,那么区别在于DbContext是特定持久性技术的表示,而存储库是一个技术不可知的持久性抽象。它是包含实体的东西的表示,但不应该公开用于实现它的技术(xml、数据库、文件存储、内存等等)。
一般来说,我自己不会这么做。概括是很困难的,而且几乎总是需要很长的时间。开发人员喜欢概括和"代码重用"的想法,但他们很少在解决方案中引入代码混淆和复杂性。一旦你开始重复自己,就要努力创造出有效的东西并加以推广。不要试图提前创建这个,因为你几乎肯定会得到一些无用的(或接近的)东西。此外,我看不出你带来了什么;如今的orm映射器是非侵入性的,而且使用起来很简单。你还提到了一个通用的表示层,没有什么比表示更具体的了,所以我也看不到它的好处(但如果你发布一些代码或解释更多)。