6

我正在构建一个MVC3应用程序,试图使用IoC和构造函数注入。我的数据库(目前为止)大约有50个表。我使用EF4(w/POCO T4模板)作为我的DAC代码。我正在使用存储库模式,每个表都有自己的存储库。我的服务层中的服务类被注入到这些存储库中。为服务层设计DI(构造函数注入)库

问题:我的服务类越来越多,他们需要的存储库。在某些情况下,我正在接近10个储存库,并开始闻起来。

是否有一种常见的方法来设计存储库和服务类,使服务不需要这么多的存储库?

这里有我的想法,我只是不知道哪一个是正确的:

1)这是一个迹象,我应该考虑合并/编组我的仓库到表中的相关部分,减少的数量或依赖库每服务类别。但是,这种方法的问题在于它会使我的存储库膨胀并使其复杂化,并使我无法为所有存储库(数据检索/更新的标准方法)使用通用接口。

2)这是一个标志,我应该考虑根据我的存储库(表格)将我的服务分成组。问题在于我的一些服务方法共享通用实现,并且在类之间打破这些方法可能会使我的依赖关系复杂化。

3)这是一个迹象,我不知道我在做什么,并有一些根本错误,我甚至无法看到。

UPDATE:对于我如何实现EF4和资料库的想法,请在CodePlex上this sample app(我用version 1)。然而,看看那里(和这里)的一些评论,看起来像我需要做更多的阅读,以确保这是我想要采取的路线 - 听起来可能不是。

+0

EF4或4.1?存储库模式和工作单元在4.1中的'DbContext'模板的上下文中构建(也许,可以对模板进行单线调整...) –

+0

EF4(不是4.1)。我应该考虑转向4.1吗?迁移有多难? –

+0

您需要抛弃旧的模板/模型代码生成,并生成一个新模板,但类名相同。只需点击几下即可。你的上下文(也可能是数据集)上的一些基本方法将会中断,这取决于你使用多少种方法来影响它们的影响程度。我相信这些将主要是文本上的变化,而不是交换出很多逻辑。 –

回答

6

Chandermani is right你的一些表可能不是核心领域类。这意味着除了单一类型的父实体之外,您不会搜索该数据。在这些情况下,您可以将它们视为“复杂类型”而不是全面实体,而EF仍将照顾您。

我使用存储库模式,每个表都有自己的仓库

我希望你没有这些你自己从头开始编写。

EF 4.1已经实施the Repository PatternDbSet)和the Unit of Work patternDbContext)。旧版本也是如此,尽管通过将这些属性更改为IDbSet,可以轻松调整DbContext模板以提供干净的可模仿实现。

虽然我看过几篇教程文章,但人们仍然在写自己的文章。这对我来说很奇怪,因为他们通常不提供理由,除了他们“实施存储库模式”这一事实。

为访问方法(如FindById)为这些存储库编写包装会使访问变得稍微容易一些,但正如您所看到的,付出的努力可能很少,可能回报很少。就个人而言,除非我发现有一些有趣的领域逻辑或复杂的查询需要封装,否则我甚至不会直接对IDbSet使用Linq

我的服务层中的服务类被注入到这些存储库中。

即使您选择使用自定义查询包装,你可以选择简单地注入DbContext,并让服务代码实例,它需要的包装。你仍然能够嘲笑你的数据访问层,你将无法模拟包装代码。尽管如此,我仍然建议你注入一些不太通用的东西,因为复杂的实现正是你希望能够在维护中进行分解的类型,或者用模拟代替。

+0

谢谢@Merlyn。我没有使用4.1,所以我会考虑转向它。现有的4.0实现不会太难吗?即使是这样,如果权衡是值得的,我仍然可能会这样做。我的存储库目前使用模型的泛型继承自基类:'UserRepository:Repository '。所以这只是对每个模型(表格)重复的单行声明。我实际上使用SQL来编写脚本,并将其复制/粘贴到文件中。但我没有为任何存储库做任何特定的事情。我会用更多的细节更新我的答案。 –

+0

那么,我会试着解释我的设计,但是意识到这对于我现在所需要的时间来说太复杂了(需要去工作)。我通过链接到我建模的应用程序来更新我的OP,但看起来我需要重新考虑这一点,因为它现在正在得到一些负面报道。真棒。我希望我能找到一篇好文章,介绍使用EF4(.1)建立一个好的可测试MVC应用程序的基础知识。这就是我在查看那篇文章时最初寻找的内容,但不幸的是,这看起来像是让我走错了路。 –

6

如果你看DDD Aggregate Root模式,并尝试在这个角度看你的数据,你会意识到,许多表没有独立的存在。他们的数据仅在父母的情况下有效。他们的大部分操作都需要您获取父项。如果可以将这些表分组并找到父实体\存储库,则可以删除所有其他子存储库。将父母孩子关联起来的复杂性直到现在您将在业务层中进行(假设您正在使用独立回购检索父母和孩子)不会转移到DAL

重构服务界面也是一个可行的选择,和任何常见的功能可以被移动到一个基类和/或可以被定义为一种服务,它是由您所有的现有服务(是A和有A)

1

@Chandermani有一个关于聚合根的好点。存储库不应该需要与表格进行1:1映射。

获取大量的依赖注入是一个很好的迹象,你的服务做得太多。遵循单一职责原则,并将其重构为更易于管理的部分。

0

是您的服务写入所有的存储库?我发现我的服务与存储库非常接近,它们提供了存储库公开的CRUD操作的业务逻辑。

+0

在大多数情况下,是的,但我的服务跨越国界的确有更复杂的情况。但是我这样做是为了让我的控制器不那么复杂,使一些更复杂的逻辑远离控制器和服务。在某些情况下,我甚至会注入其他服务。例如,我的Discussion服务将Permission服务注入到它中,以便这些服务可以在提交讨论前确保适当的授权。但也许这不是要走的路? –