【发布时间】:2021-05-16 20:04:34
【问题描述】:
我有一个多租户应用程序,对于每个 HTTP Request,它应该验证 Headers 的属性 AccountId。
全局查询过滤器是隔离.NET Core Docs 中提到的租户的好方法,但它没有列出在每次请求后如何处理状态。
这是一个例子:
ApplicationDbContext.cs
使用FooHeaderService 注入的AccountId 为Account 实体提供全局查询过滤器
private readonly IFooHeader _fooHeaders;
public ApplicationDbContext(IFooHeader fooHeaders) : base(options)
{
this._fooHeaders = fooHeaders;
}
protected override void OnModelCreating() {
FooHeaders foo = this._fooHeaders.GetFooHeaders().AccountId;
// or using Microsoft.EntityFrameworkCore.Infrastructure
FooHeaders foo = this.Database.GetService<IFooHeaders>();
Guid fooId = foo.AccountId; // MUST DISPOSE BETWEEN REQUESTS!
// Global Query Filter
modelBuilder.Entity<Account>()
.HasQueryFilter(filter => filter.AccountId = fooId)
}
FooHeaderService
为AccountId 获取Headers
public class FooHeaderService : IFooHeaders
{
private readonly FooHeaders _headers;
public FooHeaderService(IHttpContextAccessor contextAccessor)
{
_headers.AccountId = contextAccessor.HttpContext?.Request
.Headers["accountId"].ToString();
}
public FooHeaders GetFooHeaders() => _headers;
}
Startup.cs
将FooHeaderService注册为ScopedService
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IFooHeader, FooHeaderService>();
services.AddDbContext<ApplicationDbContext>();
}
问题
如果没有正确处理,OnModelCreating() 中的变量fooId = AccountId 会在HTTP Requests 之间持续存在(非常危险的东西!)。
您如何将FooHeaderService 依赖注入OnModelCreating() 并为每个HTTP Request 循环处理状态?
【问题讨论】:
-
您将上下文和服务注册为范围,因此您应该为每个请求获取新实例。所以上面的一切都应该正常工作。你确定这就是你的代码的样子吗?此外,如果您需要处置服务类型,请实施 IDisposable 以便在其范围结束后处置实例
标签: c# entity-framework dependency-injection entity-framework-core