2017-06-06 45 views
1

我最近加入了一个在整个解决方案中使用存储库模式和依赖注入的大型团队/项目。我注意到版本库接口位于数据层项目中,需要业务层项目直接依赖它。我的理解是,在使用DI时,您想要反转此依赖性以将业务逻辑与数据访问(业务层的数据引用接口)分离。当我向球队提出这个建议时,反应不一。他们没有看到好处并且反对它(“每个人都知道不直接引用具体类型”,“我们永远不需要更换我们的数据访问技术”等)。使用DI时,存储库接口属于哪个层?

将存储库接口与实现(数据层)保存在同一项目中是否是一种好的做法?如果业务层仅引用来自数据层的存储库接口,那么这种设置是否存在缺陷?

+0

不,这不是一个好习惯,但可以在一分钟内解决 –

+0

这个问题对于SO来说太广泛了。请查看[问]关于SO问题的详细信息 –

+0

@TimHutchison:如果我可以说,太宽泛但很有意思。 – Steven

回答

2

这一切都取决于。一个wise man一旦said

摘要[应]由上/政策层拥有

,你可能读马克西曼的优秀图书Dependency Injection in .NET,在那里他显示情况下,这种原则(见2.2第一版和第二版中的第三章),并以你所描述的确切场景(即版本库界面作为域层的一部分)为例。

Mark Seemann为此做出的最重要的论据是因为它允许您用不同的数据访问技术替代您的数据访问技术,这可能是您可能想到的更可能的情况,特别是考虑到我们生活的世界正确现在所有的事物都转移到了云端和云端,您可能没有(或想要)使用相同的数据访问技术。

但还有其他原因希望将核心层(域层)与应用程序的其余部分隔离开来,并让所有内容都依赖于应用程序的最重要部分。

想到的一件事就是让开发人员不可能意外地将此图层与系统中易变(或不纯)部分耦合在一起,从而导致以后难以更改。对数据访问功能的依赖是一件显而易见的事情,因为它可以使测试变得更加困难,但也考虑偶然地将域层耦合到System.Web,使开发人员可以在系统的该部分使用HttpContext。机会很大,一旦你有一个依赖项(从域层到数据访问层),随着时间的推移将变得更难。

另一方面,这种高隔离度是否有利于您的应用程序显然取决于很多因素。特别是当这种应用程序已经被设计好时,最好先把注意力放在其他改进上。

不要忘记,Dependency Inversion Principle(DIP)和依赖注入(DI)最重要的部分是类取决于抽象。这样可以实现松耦合,松耦合可以提高可维护性。由于这些开发人员已经开始练习DI,他们已经处于一个很好的位置。

我做的一个典型改进是摆脱大部分存储库,并引入更高级别的概念,例如a generic abstraction over business operations,通用abstraction over queries以及有时候域事件。这限制了在 Domain域内库的使用。在介绍这一点时,这是一个伟大的时刻,可以颠倒使用这些概念的新代码(或已迁移代码)的依赖关系,而不是通常违反大多数SOLID原则的抽象代码I[EntityName]RepositoryI[EntityName]Service

我主张的另一件事是阻止应用程序的核心层依赖某个第三方日志库的日志抽象。这再次归结为DIP,指出应用程序应该拥有抽象,当应用程序依赖于第三方抽象时,情况并非如此。这就是为什么我推销像this

2

就我个人而言,我一直都有从最低级到最高级的“流动”依赖关系。 UI需要与业务逻辑交互,因此它取决于服务接口。服务/业务逻辑需要数据访问,因此它取决于存储库接口。

这是我在大多数代码库中看到的一般方法。

+1

这很令人伤心,因为这是[DI要解决的问题](https://stackoverflow.com/a/9503612/181087)。松耦合意味着当你添加一个依赖项时,你不会拖拽其他依赖项。 – NightOwl888

+0

我想你完全是误解我的意思。我使用组合根。当然,如果需要存储库,服务层将依赖某种IRepository接口。如果没有可用的IRepository,DI并不意味着该服务可以以某种方式奇迹般地运行。 @ NightOwl888 – user9993

+1

如果将界面移至业务/域层,则可以在项目级别删除对数据层的依赖关系,这感觉就像是一种更简洁的方法。我喜欢围绕业务逻辑构建/测试而不受外部依赖关系的影响。 – user2577288

-2

它属于应用程序中的数据访问层。