【问题标题】:.NET: Abstracting away the datasource and datacontext.NET:抽象出数据源和数据上下文
【发布时间】:2012-03-13 17:35:34
【问题描述】:

我正在尝试为我最常见的开发场景编写可重用组件:

我已经制作了一个通用的表示层来表示要封装在域对象中的域对象和数据对象(dc-serializable)。我还有某种域状态/上下文,我在其中保留了所有域对象实例的引用。这个想法是域对象具有特殊的集合,当它们第一次被按需访问时,这些集合会从数据源中填充。我认为这不完全是“DDD”,但它似乎有效......

无论如何,现在我被困在 datacontext 和 datasource-part 上。我一直在思考如何存储数据并与数据源交互; zip 文件、sql-server、sql-lite-files、实体框架、nhibernate、linqtosql、mongodb 等中的 xml,我无法决定使用什么。看来我需要抽象出数据源和数据上下文,而是决定在每个应用程序中使用什么。重要的是我没有在特定框架上嵌入任何硬依赖。

抽象出数据上下文和数据源,并且仍然可以轻松地与各种现有框架一起工作,这是否现实?我想错了吗?这是一个死胡同吗?

我想要和需要的(我认为)是我的域状态,以便能够在数据上下文中查询符合某些条件的对象。我不确定它是否应该能够与整个对象图或仅单个数据对象一起使用,或者甚至不能使用具体类型而只能使用一些通用对象,或者是否应该为每个请求克隆它们。当我开始思考这个问题时,我感到很困惑......

嘎嘎

更新:

我将 DataContext/DatabaseContext(例如 EntityFramework)视为一个模块/层,用于将对象缓存在内存中、执行查询、从任何数据源获取和存储数据并将类型化的对象返回给消费者。是这样吗?

Repository-pattern (DDD) 和我的 DataContext 有什么区别?

更新 2:

基本上,这是我的模型(好还是坏?):

DataSource->DataContext/DataObject->DomainState/DomainObject->Presenter

【问题讨论】:

标签: .net database entity-framework domain-driven-design entitydatasource


【解决方案1】:

看来我需要抽象出数据源和数据上下文,而是决定在每个应用程序中使用什么。重要的是我没有在特定框架上嵌入任何硬依赖

这就是存储库模式。

Repository-pattern (DDD) 和我的 DataContext 有什么区别?

存储库是一种抽象与存储访问相关的所有内容的方法。它旨在满足应用程序的需求,它接收/发送回应用程序其余部分已知的对象。 DataContext 是 EF 的一个实现细节,它本身就是存储库的一个实现细节。

存储库有双重用途

  1. 允许您通过仅公开一个接口来更改存储数据的方式(更改数据库、使用 xml 文件等)。

  2. 它将您从以数据库为中心的方法的“繁琐”中解脱出来,让您专注于域。这一点非常重要,因为每次您开始首先使用 db 架构设计应用程序时,您不可避免地会尝试将应用程序的其余部分放入其中,并且您将拥有一个模仿数据库架构的贫血域。

DataSource->DataContext/DataObject->DomainState/DomainObject->Presenter

在任何应用程序中,您基本上都有查询(读取)和更新(写入)。在 99% 的情况下,域仅适用于写入,因为读取没有业务规则(没有行为),您只需选择要显示的相关数据。

所以对于写作我建议这个流程

ViewModel(输入)->域处理(实体、服务等)->域存储库

您可以通过多种方式从视图模型获取域实体,具体取决于应用程序。如果域非常简单,你几乎不需要域,视图模型将是域,在许多情况下与 db 架构相同。

供阅读

查询存储库 -> ViewModel(演示者)

当然,控制器通常会调用查询存储库,它可能会根据从存储库接收到的数据组装所需的视图模型(在简单的情况下,存储库会完全返回视图模型)。

【讨论】:

    【解决方案2】:

    也许您可以发布一些代码示例?很难准确理解您要做什么,但我会尝试回答您的一些问题,cmets。

    “这个想法是,域对象具有特殊的集合,这些集合在首次访问时从数据源按需填充。我认为这不完全是“DDD”,但它似乎有效......”

    这与延迟加载有何不同?为什么需要特殊类型的收藏?这与 DDD 有何关联?

    抽象出数据上下文和数据源,并且仍然让它在现有的各种框架下工作得很好而且很容易,这是否现实?我想错了吗?这是一个死胡同吗?

    不,它不是(这是一个死胡同)。您可以轻松创建一个与您的持久性技术无关的域模型,但您仍然需要考虑您选择的 orm 映射器的约束,例如 EF 不支持枚举,nhibernate 可以.此外,你从概括这一点中得到什么?一旦您选择了一个映射器,您就永远不会切换它,即使您这样做了,如果您的解决方案的其余部分都很好(不要分散您的 ISession/DbContext/其他任何东西等),您切换它也应该没有什么问题。

    “Repository-pattern (DDD) 和我的 DataContext 有什么区别?”

    如果您在说“我的 DataContext”时指的是例如 EF DbContext,则区别在于 DbContext 是特定持久性技术的表示,而存储库是与技术无关的持久性抽象。它代表了包含您的实体的东西,但它不应该暴露用于实现它的技术(xml、数据库、文件存储、内存中等等)。

    一般来说,我自己不会这样做。概括是困难的,而且几乎总是需要大量的时间。开发人员喜欢概括和“代码重用”的想法,但他们很少将代码混淆和复杂性引入解决方案。一旦你开始重复自己,旨在创造一些有效和概括的东西。不要试图预先创建这个,因为你几乎肯定会得到一些无用(或接近)的东西。此外,我看不出你带来了什么;今天的 orm 映射器是非侵入式的且易于使用。您还提到了一个通用表示层,没有什么比表示更具体的了,所以我也看不到这样做的好处(但也许如果您发布一些代码或解释更多)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 2016-04-28
      相关资源
      最近更新 更多