c# - mvc core中注册DI时如何访问ISession

标签 c# dependency-injection asp.net-core simple-injector

我在 Mvc Core 中为我的 DI 使用 SimpleInjector,我有一个在构造函数中接受 ISession 的类。

public SessionAppAdminAuthorization(ISession session )

我需要在 StartUp.Configure 方法中的 DI 配置中注册它,但我不知道如何获取作用域 session 变量。

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

最佳答案

ASP.NET Core 的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>();

    // ...
}

虽然这会有效地解决您的问题,但您可能需要更进一步。一般来说,最好从应用程序组件中隐藏框架组件和抽象,例如 IHttpContextAccessorHttpContextISession。相反 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>();

    // ...
}

关于c# - mvc core中注册DI时如何访问ISession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40744009/

相关文章:

javascript - 动态添加按钮省略确认

c# - Azure Blob 存储 - 上传 Blob 后如何获取 Blob 存储 ID?

c# - 在 .NET Core 中注入(inject) DynamoDBContext 实例的最佳方式

AngularJS 依赖注入(inject) VS ES6 导入

c# - ImageProcessorCore : Opening image takes >11seconds, 我错过了什么?

c# - 使用工作单元和存储库模式时如何从服务测试方法

C# 包装器接口(interface)错误 : E_NOINTERFACE

java - Spring DI 使用无法 beanified 的遗留对象

c# - 使用 dll 引用构建 .NET Core

c# - Asp.Net 5. Jwt token 撤销