存储库或不存储库

时间:2014-04-29 11:05:17

标签: c# entity-framework dependency-injection domain-driven-design repository-pattern

当我第一次了解领域驱动设计时,我也被介绍到了存储库和工作模式单元,这些模式曾经似乎是那些把像洞穴人员这样的SQL查询反对数据库的酷孩子们的顶级品牌。我进入该主题的深度越深,我就越了解它们似乎不再需要了,因为 ORMs ,如 EF NHibernate 将工作单元和存储库实现为一个API,称为会话或上下文。

现在我不确定该怎么做。存储库或不存储库。我真的理解这样的论点,即这种泄漏的抽象只会使事情过于复杂,同时绝对不会增加任何可能简化数据访问的内容,但是,将我的应用程序的每个可能方面都与例如情况联系起来并不合适。 实体框架。通常,我遵循一些简单的指导原则:

  1. 域层是系统的核心,包含实体,服务,存储库......
  2. 基础设施层提供基础设施问题的域接口的实现,例如,文件,数据库,协议..
  3. 应用程序层承载一个组合根,用于连接并编排所有内容。
  4. 我的解决方案通常如下所示:

    Domain.Module1
    Domain.Module2
        IModule2Repo
        IModule2Service
        Module2
    Infrastructure.Persistence
        Repositories
            EntityFrameworkRepositoryBase
    MyApp
        Boostrapper
            -> inject EntityFrameworkRepositoryBase into IRepository etc.
    

    我使用IRepository<'T>保持我的域图层清洁,IModule2Service也是域关注点,不依赖于告诉我如何访问数据的任何其他内容。当我现在要对DbContext进行需要数据访问的具体实现时,我必须注入{{1}},然后将其直接耦合到基础结构层。 (来到Visual Studio项目,由于循环依赖性,这最终会变得非常棘手!

    另外什么可以替代存储库作品? CQRS?如何抽象出一个纯粹的基础架构?

1 个答案:

答案 0 :(得分:3)

&#34;存&#34;洛尔....

无论如何,你说得对,你不希望域耦合到EF,这就是为什么你的存储库界面中的 T 应该域聚合根 EF实体(或设计为与EF正常工作的&#39;域对象)。

您的域层永远不会与持久性相关联,因为它只知道抽象。当 Module2Service 需要数据访问时,它要么使用DAO(或存储库 - 不一定是DDD版本 - 如果有意义),要么服务本身是在DAL中实现的(如果它没有实现)包含业务逻辑。)

在您的情况下,最好的方法可能是DAO /存储库,它当然会隐藏&#39; EF部分。如果你似乎写了太多的代码,那么你真的不是,我认为保持正确的关注点比保存50 LoC(整整5-10分钟)最重要。

CQRS对于富域来说总是好主意但是作为任何解决方案它都需要更多的代码(我知道每个编码器都是懒惰的,但我们需要做一个&#39; fuckton& #39;工作,应用程序不构建自己,可维护的应用程序在开始时甚至更多的工作)。 如果通过抽象一个纯粹的基础结构框架来表示隐藏EF,那么存储库是您最好的选择,而您甚至不必将该类命名为“存储库”,它是重要的原则。这就是回购的作用:摘要域的持久性。