У меня есть метод расширения объекта HttpApplicationState для получения моего контейнера IoC из приложения. Этот же код также создаст контейнер, если он не существует.
У меня есть 2 вопроса:
Введите код следующим образом:
private const string GlobalContainerKey = "UnityContainerKey";
public static IUnityContainer GetContainer(this HttpApplicationState application)
{
var container = application[GlobalContainerKey] as IUnityContainer;
if (container == null)
{
try
{
application.Lock();
container = application[GlobalContainerKey] as IUnityContainer;
if (container == null)
{
container = new UnityContainer();
application[GlobalContainerKey] = container;
}
}
finally
{
application.UnLock();
}
}
return container;
}
Вам нужно поставить
var container = application[GlobalContainerKey] as IUnityContainer;
в замке, в противном случае многие потоки могут последовательно создавать новый контейнер.
private const string GlobalContainerKey = "UnityContainerKey";
private const object lockObject = new object();
public static IUnityContainer GetContainer(this HttpApplicationState application)
{
var IUnityContainer container = null;
lock (lockObject)
{
container = application[GlobalContainerKey] as IUnityContainer;
if (container == null)
{
container = new UnityContainer();
application[GlobalContainerKey] = container;
}
}
return container;
}
Двойная проверка с помощью блокировки используется внутри кода .NET Framework для одиночных (например, System.Web.Profile.ProfileManager).
Итак, я думаю, что ваша реализация в порядке.
Почему вы впервые проверяете "container == null"? Я думаю, вы должны сначала заблокировать, а затем проверить, что контейнер равен null. Всевозможные хитроумные вещи могут произойти между первым if и return в других потоках.
Технически это не будет работать с учетом спецификации EMCA. Джон Скит рассказывает об этом в своем FAQ на С#:
http://www.yoda.arachsys.com/csharp/singleton.html
В частности, см. раздел с "Третьей версией"
Я хотел бы прочитать дальше и использовать его предложение о том, как реализовать синглтон, чтобы понять, как реализовать то, что вы пытаетесь сделать.