Dependency injection 在进行构造函数或setter注入时,依赖项的正确粒度是多少?
我试图为自己定义一些依赖注入准则。在为要通过构造函数或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
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接口的实现)
为什么存储库不能简单地将接口用作依赖项?接口是否未涵盖实现的所有公共方法?如果没有,接口是不是一个有用的抽象
我无法完全拼凑出您正在尝试做什么以及依赖项是如何工作的,但我最好的猜测是:
您正在谈论对存储库进行单元测试,但这通常是毫无用处的,因为存储库是您访问数据库的网关,并且与数据库有很强的耦合。单元测试应该单独进行,但存储库只能使用数据库进行测试。因此:集成测试 如果您能够从存储库中抽象出特定于数据库的逻辑(就像您正在做的那样),那么就没有什么需要测试的了,因为存储库的职责是与数据库通信。如果还有很多东西要测试,那么。。。在这种情况下,您的存储库类可能违反了,这使得您的存储库很难维护
因此,由于您通常会使用数据库来测试存储库本身,从测试的角度来看,注入什么并不重要,因为您必须以这样的方式构建存储库,它无论如何都能够连接到数据库。我有意不在问题中附加Java标记。这个问题是概念性的,它同样适用于.net(如果您属于它)。困境在于API的可用性和单元测试之间的折衷。我以repository为例,但它可能是一个有许多使用者的框架类。为了向您提供更多上下文,SqlSessionTemplate是SqlSession的一个实现,但它并不完全遵守接口约定。换句话说,在国际海事组织,它违反了LSP(里斯科夫替代原则)。SqlSession接口可以被认为是轻型ORM映射器。从概念上讲,DataSource类似于ADO.net SqlConnection。我知道集成测试应用于存储库的不仅仅是单元测试。我以存储库为例。它可以是服务类,也可以是低级框架类。您可以使用非存储库类来可视化这种情况。