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>();
// ...
}
Существует некоторый контекст отсутствует в этом вопросе. Вам нужно описать, где вам нужно получить этот «ISession». – Steven
В методе 'StartUp.Configure' я обновил вопрос. –
Что мешает вам получить эту переменную 'ISession' и что такое' ISession'? Пожалуйста, покажите пример того, как вы получите/используете этот «ISession» без простого инжектора. – Steven