我在 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>();
// ...
}
虽然这会有效地解决您的问题,但您可能需要更进一步。一般来说,最好从应用程序组件中隐藏框架组件和抽象,例如 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>();
// ...
}
关于c# - mvc core中注册DI时如何访问ISession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40744009/