gpt4 book ai didi

c# - ASP.NET Core - 依赖注入(inject) - IdentityServer4 DbContext

转载 作者:行者123 更新时间:2023-11-30 21:40:51 25 4
gpt4 key购买 nike

我一直在努力寻找让我的 RoleService 获得 ConfigurationDbContext (IdentityServer4) 的最佳/首选方法。

我真的很想解耦,这样我的 RoleService 就可以测试了。

我发现访问 ConfigurationDbContext 的唯一方法是在 Startup.cs 中创建一个 public static IServiceProvider:

public class Startup
{
private readonly IHostingEnvironment _environment;

// THIS IS THE PROPERTY I USED
public static IServiceProvider ServiceProvider { get; private set; }

public ConfigurationDbContext GetConfigurationDbContext()
{
return null;
}

public Startup(ILoggerFactory loggerFactory, IHostingEnvironment environment)
{
loggerFactory.AddConsole(LogLevel.Debug);
_environment = environment;
}

public void ConfigureServices(IServiceCollection services)
{
var connectionString = DbSettings.IdentityServerConnectionString;
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

// configure identity server with in-memory stores, keys, clients and scopes
var identityServerConfig = services.AddIdentityServer()
.AddConfigurationStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddSigningCredential(new X509Certificate2(Path.Combine(_environment.ContentRootPath, "certs", "IdentityServer4Auth.pfx"), "test"));

identityServerConfig.Services.AddTransient<IResourceOwnerPasswordValidator, ActiveDirectoryPasswordValidator>();
identityServerConfig.Services.AddTransient<IProfileService, CustomProfileService>();
services.AddDbContext<ConfigurationDbContext>(options => options.UseSqlServer(connectionString));
services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
ServiceProvider = app.ApplicationServices;
// other code emitted
}
}

然后在 RoleService.cs 中使用这段代码:

public class RoleService : IRoleService
{
public async Task<ApiResource[]> GetApiResourcesByIds(int[] ids)
{
ApiResource[] result;

using (var serviceScope = Startup.ServiceProvider.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
result =
context.ApiResources.Where(x => ids.Contains(x.Id))
.Include(x => x.Scopes)
.Include(x => x.UserClaims)
.ToArray();

return result;
}
}
}

这是在 RoleService.cs 中获取依赖项的最佳方式吗?

有没有办法抽象serviceScope(因为它在using语句中,可能是IDisposable,我真的不知道是否有办法抽象获取上下文?

还有其他建议或最佳做法吗?

最佳答案

您可以通过创建一个将所需依赖项作为构造函数参数的构造函数,将依赖项传递给 RoleService

根据您的 RoleService 的生命周期(无法根据提供的代码判断),您可以将 ConfigurationDbContext 直接传递给 RoleService 如果服务已经是 Scoped。或者您将传递 IServiceScopeFactory 以在您的服务中手动创建范围。

类似于:

private readonly IServiceScopeFactory _scopeFactory;

public RoleService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}

public async Task<ApiResource[]> GetApiResourcesByIds(int[] ids)
{
using (var scope = _scopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
}
}

由于您的方法与 DbContext 紧密耦合(这不一定是坏事),您可能最终会创建内存中的 ConfigurationDbContext。您使用的 IdentityServer4.EntityFramework 存储库有一些用于测试的示例 here .

关于c# - ASP.NET Core - 依赖注入(inject) - IdentityServer4 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44124768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com