具有依赖注入的单例 class c#
Singleton class with Dependency Injection c#
我们有一个带有 QCServiceLog class 的外部项目,它具有由 Unity 解析的 ILogging 依赖项。
但是 QCServiceLog 是一个 Singleton class 正如你在下面的例子中看到的那样:
private readonly ILogging _logging = null;
private static QCServiceLog _instance = null;
public static QCServiceLog Instance
{
get
{
return _instance;
}
}
public QCServiceLog(ILogging logging)
{
_logging = logging;
if (_instance == null)
{
_instance = this;
}
}
我们正在尝试使用它,在我们的解决方案中,我们进行了如下注册:
uc.RegisterType<ILogging, QCFileManager>(new ContainerControlledLifetimeManager());
但是由于 QCServiceLog 是一个单例,我们认为代码永远不会通过构造函数,所以 _instance 永远不会被实例化。
我们正在使用它来做这个:
QCServiceLog.Instance.Log(ex);
单例实现正确吗?我们相信它永远不会做 QCServiceLog 的 new。
你怎么看?在不更改外部项目的情况下,我们可以做些什么?
您可以想象的例外是:
对象引用未设置为对象的实例。
非常感谢您的帮助!
Is that Singleton implemented correctly?
是的。但是它需要先从容器中实例化,然后才能获得它的静态实例。
换句话说,你不能使用这一行:
QCServiceLog.Instance.Log(ex);
直到您第一次致电:
container.Resolve<QCServiceLog>();
(假设您已经使用 Unity 注册了 ILogging
的实例)因为第一次调用不会命中构造函数来填充 _instance
值。
你最好直接在需要的地方注入它:
public class Foo(QCServiceLog log)
或者制作一个包装器 class,其中包含在使用它之前正确连接它的逻辑,通过您的 DI 容器注入。
无论哪种方式,您都应该注意 DI 主要用于您的应用程序。第 3 方实用程序不一定以 DI 友好的方式做事,因此您可能需要使用 facade or adapter 以使它们在您的应用程序上下文中使用 DI 友好。
您提供的代码不是线程安全的 - 请在此处查看 Implementing the Singleton Pattern in C#:
public QCServiceLog(ILogging logging)
{
_logging = logging;
if (_instance == null)
{
_instance = this;
}
}
另一个问题是构造函数没有被隐藏。因此,即使您的 IoC 容器将 class 注册为单例,仍然可以使用 new
运算符在代码中的任何位置构造此 class 的实例。我在我工作的应用程序中发现了内存泄漏,这是由这件事引起的(目的是使用 via DI/IoC,它被注册为单例,但通过代码手动更新。
我们有一个带有 QCServiceLog class 的外部项目,它具有由 Unity 解析的 ILogging 依赖项。 但是 QCServiceLog 是一个 Singleton class 正如你在下面的例子中看到的那样:
private readonly ILogging _logging = null;
private static QCServiceLog _instance = null;
public static QCServiceLog Instance
{
get
{
return _instance;
}
}
public QCServiceLog(ILogging logging)
{
_logging = logging;
if (_instance == null)
{
_instance = this;
}
}
我们正在尝试使用它,在我们的解决方案中,我们进行了如下注册:
uc.RegisterType<ILogging, QCFileManager>(new ContainerControlledLifetimeManager());
但是由于 QCServiceLog 是一个单例,我们认为代码永远不会通过构造函数,所以 _instance 永远不会被实例化。 我们正在使用它来做这个:
QCServiceLog.Instance.Log(ex);
单例实现正确吗?我们相信它永远不会做 QCServiceLog 的 new。
你怎么看?在不更改外部项目的情况下,我们可以做些什么? 您可以想象的例外是:
对象引用未设置为对象的实例。
非常感谢您的帮助!
Is that Singleton implemented correctly?
是的。但是它需要先从容器中实例化,然后才能获得它的静态实例。
换句话说,你不能使用这一行:
QCServiceLog.Instance.Log(ex);
直到您第一次致电:
container.Resolve<QCServiceLog>();
(假设您已经使用 Unity 注册了 ILogging
的实例)因为第一次调用不会命中构造函数来填充 _instance
值。
你最好直接在需要的地方注入它:
public class Foo(QCServiceLog log)
或者制作一个包装器 class,其中包含在使用它之前正确连接它的逻辑,通过您的 DI 容器注入。
无论哪种方式,您都应该注意 DI 主要用于您的应用程序。第 3 方实用程序不一定以 DI 友好的方式做事,因此您可能需要使用 facade or adapter 以使它们在您的应用程序上下文中使用 DI 友好。
您提供的代码不是线程安全的 - 请在此处查看 Implementing the Singleton Pattern in C#:
public QCServiceLog(ILogging logging)
{
_logging = logging;
if (_instance == null)
{
_instance = this;
}
}
另一个问题是构造函数没有被隐藏。因此,即使您的 IoC 容器将 class 注册为单例,仍然可以使用 new
运算符在代码中的任何位置构造此 class 的实例。我在我工作的应用程序中发现了内存泄漏,这是由这件事引起的(目的是使用 via DI/IoC,它被注册为单例,但通过代码手动更新。