Я создал оболочку для контейнера Ninject DI, которую я намерен использовать в приложении WPF. Я хотел бы, чтобы это было поточно-ориентированным на случай, если мне понадобится открывать новые окна в отдельных потоках, но я запутался в использовании ключевого слова volatile и блокировки. Насколько я знаю, блокировка довольно проста для понимания, но я не склонен использовать ключевое слово volatile . Исходя из результатов поиска в Google, я пришел к выводу, что ключевое слово 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 , или я могу опустить эту часть, так как они более или менее доступны только для чтения в этой конструкции. Буду признателен, если кто-нибудь сможет пролить свет на это.