依赖注入和单例。他们是两个完全不同的概念吗?


17

我一直在听说要为我的同事在Singleton上使用依赖项注入。我仍然无法确定它们是否是可以互相替换的两个正交图案?还是DI是使Singleton模式可测试的方法?

请看下面的代码片段。

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

所述SingletonConsumer正在接受类型的参数IMathFace。而不是在内部访问singleton类,而是SingletonConsumer将获得调用者传递的singleton实例。这是通过依赖注入使用单例类的一个好例子吗?


您能告诉我DI如何取代单例吗?

7
Singleton是一种设计模式。DI / IoC是一种技术。
戴夫

2
DI不能替代Singleton,就像香蕉可以替代化油器一样。它们是完全不同的概念。
戴夫

所以我的例子是有效的。

1
是的,但它可能会在封装的费用(这也是非单真)看到:stackoverflow.com/questions/1005473/...

Answers:


17

我认为他的意思是您应该使用依赖注入来注入服务的单个实例,而不是将经典的Singleton实现与静态访问器一起使用MySingleton.Instance

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

使用经典的单例实现,您的所有代码都依赖于该服务为单例。您基本上可以在每次使用时将该假设硬编码为使用代码MySingleton.Instance

另一方面,使用DI可以将服务的实例传递到构造函数中并进行存储。该服务只有一个实例是实现细节。您可以轻松地对其进行更改,以使使用方代码具有不同的实例。这样,您就有一些类/接口恰好由单个实例实现,而不是强制只有一个实例。

例如,如果您想要模拟服务的实现以进行测试,或者程序的不同部分需要该服务的不同配置,则这很有用。


4

你是对的。而不是通过单例访问对象,您传递了对它的引用,因此您在使用构造函数注入。

其他人指出的是这些概念无关。消费单例实例没有什么特别的,因为要注入的对象并不真正关心注入的对象来自何处。


3

在单例模式和DI / IoC相交的情况下,单例的注入是一种情况。

大多数DI框架都可以配置为实例化注入对象的单个实例。任何请求此类对象实例的使用者对象都将获得相同的单个实例。根据定义,该实例为Singleton。关于概念上的重叠就是这样。


2

这里的混乱之处在于,已经将两个概念混为一谈:单例和单例实例的静态访问器/网关。

如您所知,您的同事建议注入依赖项,而不是使用Singleton.Instance(静态网关)直接访问。

之所以与单例模式没有任何关系,是因为相同的DI概念同样适用于用实例化一个非单例对象new Foo()。依赖项将被注入,而不管它是否是单例实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.