我爲Ninject DI容器創建了一個打包器,我打算在WPF應用程序中使用它。我希望它是線程安全的,以防我需要在分開的線程中打開新窗口,但我對使用volatile關鍵字和鎖定感到困惑。儘管我知道,鎖定非常直截了當,但我並不支持使用易失性關鍵字。從我的搜索結果中,我瞭解到volatile關鍵字可確保多線程環境中指定實例的安全讀取訪問,但在指定實例佔用的內存空間發生更改時不提供任何安全措施。我用的是線程安全的單模式的一些例子結合我的解決方案,並與該包裝,將成爲我作爲一個服務定位器上來:爲DI容器創建線程安全的單例包裝器
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。鎖定是好的。另外,當我讀到「有人可以撕掉一些光」時,我咯咯地笑着,想着如果只有查克·諾里斯能讀到這個:) –
那麼,我們都有我們的「特殊時刻」......謝謝你的回答。 – Stanque