CodeGo.net>为DI容器创建线程安全的单例包装
作者:互联网
我为Ninject DI容器创建了一个包装,打算在WPF应用程序中使用.我希望它是线程安全的,以防我需要在单独的线程中打开新窗口,但是对于使用volatile关键字和锁定我感到困惑.就我所知,锁定非常容易理解,但是我并不是在使用volatile关键字.从我的谷歌搜索结果中,我了解到volatile关键字可确保在多线程环境中对指定实例进行安全的读取访问,但在更改指定实例所占用的内存空间时不会提供任何安全性.我将解决方案与一些线程安全的单例模式示例结合在一起,并提出了此包装器,该包装器将用作服务定位器:
public class NinjectResolver
{
private static object syncRoot = new object();
private static volatile NinjectResolver instance = null;
private static volatile IKernel kernel = null;
public static NinjectResolver GetInstance()
{
lock (syncRoot)
{
if (instance == null)
instance = new NinjectResolver();
}
return instance;
}
static NinjectResolver()
{
lock (syncRoot)
{
if (kernel == null)
kernel = new StandardKernel();
}
}
public void AddBindings(Dictionary<Type, Type> bindings)
{
lock (syncRoot)
{
foreach (var binding in bindings)
{
Type IType = binding.Key;
Type ImplementationType = binding.Value;
kernel.Bind(IType).To(ImplementationType);
}
}
}
private NinjectResolver()
{
}
/// <summary>
/// Resolves All dependencies for requested instance and returns that instance
/// </summary>
/// <typeparam name="T">Requested Implementation type</typeparam>
/// <returns>Instance of Implementation type</returns>
public T Resolve<T>()
{
return kernel.TryGet<T>();
}
/// <summary>
/// Resolves property injection dependencies in already instantiated Implementation types
/// </summary>
/// <param name="obj">Specified instance of implementation type</param>
public void Inject(object obj)
{
kernel.Inject(obj);
}
}
我的问题是:由于初始化将在App.xaml.cs(首先调用GetInstance())内进行,我是否需要在指定的位置使用锁定,并且这些静态字段是否需要声明为volatile或我可以省略该部分?因为在此结构中它们或多或少是只读的.如果有人能对此有所了解,我将不胜感激.
解决方法:
要实现线程安全的单例模式,您基本上有两个选择:
1.双重检查锁定
public static NinjectResolver GetInstance()
{
if(instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new NinjectResolver();
}
}
return instance;
}
2.在声明时初始化实例
private static volatile NinjectResolver instance = new NinjectResolver();
public static NinjectResolver GetInstance()
{
return instance;
}
您也可以将代码放入静态块中,然后使用:
private static volatile IKernel kernel = new StandardKernel();
标签:multithreading,ninject,wpf,c,net-4-0 来源: https://codeday.me/bug/20191201/2084599.html