C# 通过数据库访问实现自定义IAuthorizationPolicyProvider
我使用的是asp.net core 2.1,我有一个C# 通过数据库访问实现自定义IAuthorizationPolicyProvider,c#,asp.net-core,C#,Asp.net Core,我使用的是asp.net core 2.1,我有一个IAuthorizationPolicyProvider的实现,它对数据库上下文使用了ctor注入。由于提供程序必须注册为单例,这会引发数据库上下文的作用域 因此,我将连接字符串设置对象插入到ctor中,然后使用选项生成器并在调用GetPolicyAsync时创建上下文: var optionsBuilder = new DbContextOptionsBuilder<MyContext>(); optionsBuilder.Use
IAuthorizationPolicyProvider
的实现,它对数据库上下文使用了ctor注入。由于提供程序必须注册为单例,这会引发数据库上下文的作用域
因此,我将连接字符串设置对象插入到ctor中,然后使用选项生成器并在调用GetPolicyAsync
时创建上下文:
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer(this.connectionStrings.MyContextConnection);
using (var context = new MyContext(optionsBuilder.Options))
{
// ...
}
var optionsBuilder=new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(this.connectionString.MyContextConnection);
使用(var context=newmycontext(optionsBuilder.Options))
{
// ...
}
用例在开始时被调用,是否有一种安全且更有效的方法在方法调用中获取上下文?要从
单例服务
解析范围服务
,您可以尝试在单例服务中注册IServiceProvider
public class DbPolicyProvider : IAuthorizationPolicyProvider
{
private readonly IServiceProvider _serviceProvider;
public DbPolicyProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return await GetPolicyAsync("DbPolicy");
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
using (var db = _serviceProvider.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>())
{
var policys = db.Policys.Where(p => p.Name == policyName).ToList();
var build = new AuthorizationPolicyBuilder();
foreach (var policy in policys)
{
build.RequireClaim(policyName, policy.Config);
}
return Task.FromResult(build.Build());
}
}
}
公共类DbPolicyProvider:IAAuthorizationPolicyProvider
{
私有只读服务器ViceProvider\u服务提供商;
公共数据库策略提供程序(IServiceProvider服务提供程序)
{
_服务提供者=服务提供者;
}
公共异步任务GetDefaultPolicyAsync()
{
返回等待GetPolicyAsync(“DbPolicy”);
}
公共任务GetPolicyAsync(字符串policyName)
{
使用(var db=_serviceProvider.CreateScope().serviceProvider.GetRequiredService())
{
var policys=db.policys.Where(p=>p.Name==policyName.ToList();
var build=new AuthorizationPolicyBuilder();
foreach(保单中的var保单)
{
build.requirrecall(policyName,policy.Config);
}
返回Task.FromResult(build.build());
}
}
}
要从单例服务
解析范围服务
,您可以尝试在单例服务中注册IServiceProvider
public class DbPolicyProvider : IAuthorizationPolicyProvider
{
private readonly IServiceProvider _serviceProvider;
public DbPolicyProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return await GetPolicyAsync("DbPolicy");
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
using (var db = _serviceProvider.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>())
{
var policys = db.Policys.Where(p => p.Name == policyName).ToList();
var build = new AuthorizationPolicyBuilder();
foreach (var policy in policys)
{
build.RequireClaim(policyName, policy.Config);
}
return Task.FromResult(build.Build());
}
}
}
公共类DbPolicyProvider:IAAuthorizationPolicyProvider
{
私有只读服务器ViceProvider\u服务提供商;
公共数据库策略提供程序(IServiceProvider服务提供程序)
{
_服务提供者=服务提供者;
}
公共异步任务GetDefaultPolicyAsync()
{
返回等待GetPolicyAsync(“DbPolicy”);
}
公共任务GetPolicyAsync(字符串policyName)
{
使用(var db=_serviceProvider.CreateScope().serviceProvider.GetRequiredService())
{
var policys=db.policys.Where(p=>p.Name==policyName.ToList();
var build=new AuthorizationPolicyBuilder();
foreach(保单中的var保单)
{
build.requirrecall(policyName,policy.Config);
}
返回Task.FromResult(build.build());
}
}
}
@Tao Zhou的答案对我不起作用,因为没有方法CreateScope()
相反,我使用了类中的静态方法CreateScope()
使用(var db=ServiceProviderServiceExtensions.CreateScope(\u serviceProvider.serviceProvider.GetRequiredService())
@Tao Zhou的答案对我不起作用,因为没有方法CreateScope()
相反,我使用了类中的静态方法CreateScope()
使用(var db=ServiceProviderServiceExtensions.CreateScope(\u serviceProvider.serviceProvider.GetRequiredService())
我认为这是因为AuthorizationPolicyProvider的范围仅限于请求。你不能在单例中使用作用域。实际上,它必须是单例,我将添加一些信息。我认为,因为AuthorizationPolicyProvider的作用域是请求。你不能在单例中使用有作用域的东西。事实上,它必须是单例,我将添加一些信息。