2016-11-22 5 views
0

Я использую SimpleInjector для своего DI в Mvc Core, и у меня есть класс, который принимает ISession в конструкторе.Как получить доступ к ISession при регистрации для DI в ядре mvc

public SessionAppAdminAuthorization(ISession session)

Мне нужно зарегистрировать это в конфигурации DI в StartUp.Configure методе, но я не знаю, как получить контекстный переменный сеанс.

container.Register<IAppAdminAuthorization>(() => { 
    return new SessionAppAdminAuthorization([I Need the ISession]); }, 
    Lifestyle.Scoped); 
+0

Существует некоторый контекст отсутствует в этом вопросе. Вам нужно описать, где вам нужно получить этот «ISession». – Steven

+0

В методе 'StartUp.Configure' я обновил вопрос. –

+0

Что мешает вам получить эту переменную 'ISession' и что такое' ISession'? Пожалуйста, покажите пример того, как вы получите/используете этот «ISession» без простого инжектора. – Steven

ответ

1

ASP.NET сердечника ISession можно получить доступ через HttpContext.Session собственности. Так как HttpContext - это данные времени выполнения, то и Session. Runtime data should not be injected into your components' constructors, поэтому ваш SessionAppAdminAuthorization не должен зависеть непосредственно от ISession.

Простейшее решение состоит в том, чтобы дать SessionAppAdminAuthorization вместо IHttpContextAccessor и позвонить по телефону IHttpContextAccessor.HttpContext.Session. Пример:

public class SessionAppAdminAuthorization : IAppAdminAuthorization 
{ 
    private readonly IHttpContextAccessor accessor; 

    public SessionAppAdminAuthorization(IHttpContextAccessor accessor) { 
     this.accessor = accessor; 
    } 

    public void DoSomethingUseful() { 
     if (this.accessor.HttpContext.Session.GetBoolean("IsAdmin")) { 
      // ... 
     } else { 
      // ... 
     } 
    } 
} 

Теперь вы можете сделать регистрацию следующим образом:

public void ConfigureServices(IServiceCollection services) 
{ 
    // You need to register IHttpContextAccessor. 
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

    // ... 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment e, ILoggerFactory f) 
{ 
    container.RegisterSingleton(
     app.ApplicationServices.GetRequiredService<IHttpContextAccessor>()); 

    container.Register<IAppAdminAuthorization, SessionAppAdminAuthorization>(); 

    // ... 
} 

Хотя это будет эффективно решить вашу проблему, вы можете взять его на один шаг. В общем случае лучше скрыть компоненты компонентов и абстракции, такие как IHttpContextAccessor, HttpContext и ISession из компонентов приложения. Вместо этого Dependency Inversion Principle направляет нас к абстракциям, специфичным для приложения, реализуемым адаптерами, которые позволяют переводить эти вызовы для конкретных приложений на компоненты инфраструктуры. Например:

// Application-specific abstraction (part of your application's core layer) 
public interface IUserContext 
{ 
    bool IsAdmin { get; } 
} 

// Adapter implementation (placed in the Composition Root of your web app) 
public class AspNetSessionUserContextAdapter : IUserContext 
{ 
    private readonly IHttpContextAccessor accessor; 
    public AspNetSessionUserContextAdapter(IHttpContextAccessor accessor) { 
     this.accessor = accessor; 
    } 

    public bool IsAdmin => this.accessor.HttpContext.Session.GetBoolean("IsAdmin"); 
} 

// Improved version of SessionAppAdminAuthorization 
public class SessionAppAdminAuthorization : IAppAdminAuthorization 
{ 
    private readonly IUserContext userContext; 
    // This class can now be moved to the business layer, since there's no 
    // more dependency on ASP.NET. 
    public SessionAppAdminAuthorization(IUserContext userContext) { 
     this.userContext = userContext; 
    } 

    public void DoSomethingUseful() { 
     if (this.userContext.IsAdmin) { 
      // ... 
     } else { 
      // ... 
     } 
    } 
} 

Регистрация:

public void Configure(IApplicationBuilder app, IHostingEnvironment e, ILoggerFactory f) 
{ 
    var accesr = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); 
    container.RegisterSingleton<IUserContext>(new AspNetSessionUserContextAdapter(accesr)); 
    container.Register<IAppAdminAuthorization, SessionAppAdminAuthorization>(); 

    // ... 
} 
+0

Спасибо, так как я вижу, что между SimpleInjection и Microsoft DI есть проводка, я попытаюсь также реализовать второй пример. Вы правы, что не очень элегантно включать все эти мс-файлы в мои библиотеки. –