Asp.net Mvc - Kigg: поддерживать объект пользователя в HttpContext.Items между запросами - PullRequest
1 голос
/ 13 мая 2010

Сначала я хочу сказать, что я надеюсь, что это не похоже на то, что я ленив, но у меня есть некоторые проблемы с пониманием фрагмента кода из следующего проекта.

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 уничтожаются при каждом запросе, как они предотвращают потерю своего пользовательского объекта?

В любом случае, это довольно длинный вопрос, поэтому я благодарен за любой толчок в правильном направлении.

1 Ответ

0 голосов
/ 14 мая 2010

В Ninject вы выбираете свое специальное расширение (Ninject.Web или Ninject.Web.Mvc) и используете InRequestScope для управления содержимым в «контексте .Items». Они удаляются в конце запроса, а новые будут разрешаться по мере необходимости при последующих запросах.

Это определенно не будет так много кода или так сложно, как некоторые вещи, которые вы цитируете IMO: D

...