1

Я разрабатываю веб-приложение в ASP.NET MVC5.Как использовать провайдера сеанса в проекте DI

Как и все базовые веб-приложения, у него также есть страница входа, где пользователь может аутентифицироваться самостоятельно. После проверки подлинности я хочу сохранить пару связанных с пользователем элементов в сеансе, поэтому мне не нужно каждый раз запрашивать базу данных для восстановления аутентифицированного пользователя.

После того, как вы прочитали книгу Марка Семанна об инъекции зависимостей, я хочу свободно соединить все свои слои и убедиться, что все можно легко заменить.

В настоящее время мой SessionProvider по умолчанию использует объект Session, но, возможно, в будущем это может измениться на другой тип механизма хранения.

подход я принял это с помощью Ambient контекст которой он объяснил с TimeProvider пример, но мне интересно, если это правильный подход к этой функциональности, и если это поточно (также для модульного тестирования).

Является ли мое решение надлежащим или как вы реализуете такой механизм? Это было в моей голове уже несколько дней, и кто может помочь мне определить лучшее решение?

Спасибо!

public abstract class SessionProvider 
{ 
    private static SessionProvider _current; 

    static SessionProvider() 
    { 
     _current = new DefaultSessionProvider(); 
    } 

    public static SessionProvider Current 
    { 
     get { return _current; } 
     set 
     { 
      if (value == null) 
      { 
       throw new ArgumentNullException(); 
      } 
      _current = value; 
     } 
    } 

    public abstract string UserName { get; set; } 
} 

Мой местный по умолчанию:

public class DefaultSessionProvider : SessionProvider 
{ 
    public override string UserName 
    { 
     get { return (string) HttpContext.Current.Session["username"]; } 
     set { HttpContext.Current.Session["username"] = value; } 
    } 
} 

Так у меня есть доступ в целом мое решение моей SessionProvider, является ли это реальный объект сеанса или механизм хранения базы данных с приводом ...

SessionProvider.Current.UserName = "myUserName"; 
+0

Как вы можете прочитать в книге Марка Семанна, Окружающий контекст ЧТО-НИБУДЬ правильное решение. Я бы сказал, что это НЕ правильное решение, пока не будет доказано обратное. – Steven

+0

Да, вряд ли .. Но здесь это загрязнило бы API, если бы мне пришлось передать его каждому сервису. Он используется только для запроса данных, а не для его записи. Правильный локальный стандарт существует (DefaultSessionProvider), и он гарантированно доступен. И в каком-то смысле сеанс сам по себе можно рассматривать как контекст окружения, а я думаю ... Какое решение вы предложили бы затем хранить и извлекать данные сеанса? – Jules

+0

Если вам нужно «передать его каждому сервису», у вас другая проблема. В этом случае, скорее всего, вы говорите о сквозной проблеме. Межсекторальные проблемы должны быть отделены от вашего обычного кода, например, с использованием перехвата, украшения или других аспектно-ориентированных методов программирования. – Steven

ответ

0

После проверки подлинности я хочу сохранить пару связанных с пользователем элементов в сеансе, поэтому мне не нужно запрашивать da tabase каждый раз до восстановить аутентифицированного пользователя.

Ну, похоже, вы работаете над каким-то механизмом кэширования. На самом деле не имеет значения, находится ли он в сеансе или в кеше Redis, или в кеше любого другого типа. И этот кеш является хранилищем для ключей. Я бы создал интерфейс кэша, например:

interface ICache 
{ 
    object this[string key] {get; set;} 
} 

И создать конкретные классы. SessionCache в вашем случае:

public SessionCache : ICache 
{ 
    private IHttpSessionState _session; 
    public SessionCache(IHttpSessionState session) 
    { 
     _session = session; 
    } 

    // ICache implementation goes here... 
} 

Таким образом, вы будете сузить проблему зависимостей впрыснуть объект Session для конкретного класса (SessionCache). С Ninject вы можете сделать что-то вроде:

.WithConstructorArgument("session",ninjectContext=>HttpContext.Session); 

И после того, что вы можете, наконец, сделать контроллеры зависит от ICACHE.

В проекте модульных тестов вы можете создать другой конкретный класс ICache, что-то вроде DummyCache с кешем в памяти. Таким образом, вы можете протестировать свои контроллеры, не придерживаясь объекта Session.

Смежные вопросы