3

我正在尝试为自己定义一些依赖注入指南。在为要通过构造函数或 setter 注入注入的类定义依赖项时,正确的粒度应该是多少?该类可以是服务、存储库等。假设有一个存储库类,如下所示:

public class ProductRepository 
{
    //Option-A
    public ProductRepository(DataSource dataSource)
    {
    }

    //Option-B      
    public ProductRepository(SqlSession sqlSession)
    {
    }

    //Option-C
    public ProductRepository(SqlSessionTemplate sqlSessionTemplate)
    {
    }
}

上述类所需的最小依赖是 DataSource 接口。存储库类在内部使用 SqlSessionTemplate(SqlSession 接口的实现)。如代码所示,构造函数注入有 3 种选择。以下是我的理解:

Option-A(DataSource 依赖项) 这是存储库类的最小依赖项。从消费者的角度来看,此构造函数是正确的选择,但从单元测试的角度来看,它不适合,因为 DataSource 在存储库实现中由 SqlSessionTemplate 内部使用。

Options-B (SqlSession 依赖) 从单元测试的角度来看,这是正确的选择,但从消费者的角度来看,这是正确的选择。此外,存储库实现与 SqlSessionTemplate 接口的特定实现紧密耦合。因此,如果消费者通过 SqlSessionTemplate 以外的一些不同的 SqlSession 接口,它将不起作用。

Options-C(SqlSessionTemplate 依赖项) SqlSessionTemplate 作为实现而不是接口似乎不适合单元测试。此外,与 DataSource 相比,实例化 SqlSessionTemplate 对消费者不利。因此放弃了这个选项。

Option-A 和 Option-B 似乎是可用的选择。但是,消费者的观点和单元测试的观点之间存在权衡,反之亦然。

我是依赖注入的新手。我向 DI 专家寻求建议。什么是正确的解决方案(如果有)?在上述情况下你会怎么做?

谢谢。

4

2 回答 2

0

您正在谈论对存储库进行单元测试,但这通常是没有用的,因为存储库是您通往数据库的网关并且与它有很强的耦合。单元测试应单独进行,但存储库只能使用数据库进行测试。因此:集成测试。

如果您能够从存储库中抽象出特定于数据库的逻辑(正如您似乎正在做的那样),那么就没有什么需要测试的了,因为存储库的职责是与数据库进行通信。如果还有很多东西需要测试,那么……在这种情况下,您的存储库类可能违反了单一职责原则,这使得您的存储库难以维护。

因此,由于您通常会使用数据库测试存储库本身,因此从测试的角度来看,注入什么并不重要,因为您必须以无论如何都能够连接到数据库的方式构建存储库。

于 2013-03-19T09:12:28.690 回答
0

这是存储库类的最小依赖项。

我认为这是确定合适的耦合量的起点。您应该注入不超过或少于满足要求所需的量。

这是一个非常笼统的指导方针,几乎相当于“它取决于”,但这是开始思考它的好方法。我对 DataSource、SqlSession 或 SqlSessionTemplate 的了解不够,无法在上下文中回答。

存储库类在内部使用 SqlSessionTemplate(SqlSession 接口的实现)

为什么存储库不能简单地将接口用作依赖项?接口不覆盖实现的所有公共方法吗?如果没有,接口是否甚至是有用的抽象?

我无法完全拼凑出您要做什么以及依赖项如何工作,但我最好的猜测是:

  1. 您需要通过构造函数注入 SqlSession 和 DataSource,或者
  2. 您需要通过 Repository 的构造函数注入 SqlSession,并将 DataSource 注入 SqlSessionTemplate 的构造函数
于 2013-03-18T18:28:23.810 回答