Сначала я хочу сказать, что я надеюсь, что это не похоже на то, что я ленив, но у меня есть некоторые проблемы с пониманием фрагмента кода из следующего проекта.
http://kigg.codeplex.com/
Я просматривал исходный код и заметил кое-что, что будет полезно для моего маленького проекта, который я делаю. В их BaseController они имеют следующий код:
private static readonly Type CurrentUserKey = typeof(IUser);
public IUser CurrentUser
{
get
{
if (!string.IsNullOrEmpty(CurrentUserName))
{
IUser user = HttpContext.Items[CurrentUserKey] as IUser;
if (user == null)
{
user = AccountRepository.FindByClaim(CurrentUserName);
if (user != null)
{
HttpContext.Items[CurrentUserKey] = user;
}
}
return user;
}
return null;
}
}
Это не точная копия кода, который я немного скорректировал для своих нужд. Эту часть кода я до сих пор понимаю. Они хранят свои IUser в HttpContext.Items. Я предполагаю, что они делают это так, чтобы им не приходилось вызывать базу данных каждый раз, когда им нужен объект User.
Часть, которую я не понимаю, заключается в том, как они поддерживают этот объект между запросами. Если я правильно понимаю, HttpContext.Items - это кэш-память для каждого запроса.
Итак, после еще нескольких копаний я нашел следующий код.
internal static IDictionary<UnityPerWebRequestLifetimeManager, object> GetInstances(HttpContextBase httpContext)
{
IDictionary<UnityPerWebRequestLifetimeManager, object> instances;
if (httpContext.Items.Contains(Key))
{
instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key];
}
else
{
lock (httpContext.Items)
{
if (httpContext.Items.Contains(Key))
{
instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key];
}
else
{
instances = new Dictionary<UnityPerWebRequestLifetimeManager, object>();
httpContext.Items.Add(Key, instances);
}
}
}
return instances;
}
Это та часть, где происходит какая-то магия, которую я не понимаю. Я думаю, что они используют Unity для внедрения зависимостей на каждый запрос? В моем проекте я использую Ninject, и мне интересно, как я могу получить тот же результат.
Я полагаю, InRequestScope в Ninject - это то же самое, что UnityPerWebRequestLifetimeManager? Мне также интересно, какой класс / метод они привязывают к какому интерфейсу? Так как HttpContext.Items уничтожаются при каждом запросе, как они предотвращают потерю своего пользовательского объекта?
В любом случае, это довольно длинный вопрос, поэтому я благодарен за любой толчок в правильном направлении.