Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection 在进行构造函数或setter注入时,依赖项的正确粒度是多少?_Dependency Injection_Inversion Of Control - Fatal编程技术网

Dependency injection 在进行构造函数或setter注入时,依赖项的正确粒度是多少?

Dependency injection 在进行构造函数或setter注入时,依赖项的正确粒度是多少?,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,我试图为自己定义一些依赖注入准则。在为要通过构造函数或setter注入的类定义依赖项时,正确的粒度应该是什么?该类可以是服务、存储库等。假设有一个存储库类,如下所示: public class ProductRepository { //Option-A public ProductRepository(DataSource dataSource) { } //Option-B public ProductRepository(Sq

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

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

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

    //Option-C
    public ProductRepository(SqlSessionTemplate sqlSessionTemplate)
    {
    }
}
上述类所需的最小依赖项是DataSource接口。repository类在内部使用SqlSessionTemplate(SqlSession接口的实现)。如代码所示,构造函数有3种选择来执行构造函数注入。以下是我的理解:

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

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

Options-C(SqlSessionTemplate依赖项) SqlSessionTemplate作为一个实现而不是一个接口似乎不适合进行单元测试。此外,这对使用者也不好,因为与DataSource相比,实例化SqlSessionTemplate更复杂。因此,放弃此选项

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

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

谢谢

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

我认为这是计算正确耦合量的起点。您应该注入不多于或少于满足要求所需的量

这是一个非常笼统的指导方针,几乎等同于“视情况而定”,但这是一个开始思考的好方法。我对DataSource、SqlSession或SqlSessionTemplate了解不够,无法在上下文中回答

repository类在内部使用SqlSessionTemplate (SqlSession接口的实现)

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

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

  • 您需要通过构造函数注入SqlSession和DataSource,或者
  • 您需要通过存储库的构造函数注入SqlSession,并将数据源注入SqlSessionTemplate的构造函数

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

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


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

    我有意不在问题中附加Java标记。这个问题是概念性的,它同样适用于.net(如果您属于它)。困境在于API的可用性和单元测试之间的折衷。我以repository为例,但它可能是一个有许多使用者的框架类。为了向您提供更多上下文,SqlSessionTemplate是SqlSession的一个实现,但它并不完全遵守接口约定。换句话说,在国际海事组织,它违反了LSP(里斯科夫替代原则)。SqlSession接口可以被认为是轻型ORM映射器。从概念上讲,DataSource类似于ADO.net SqlConnection。我知道集成测试应用于存储库的不仅仅是单元测试。我以存储库为例。它可以是服务类,也可以是低级框架类。您可以使用非存储库类来可视化这种情况。