c# - 在没有 BuildServiceProvider() 的情况下在 AddOpenIdConnect 中获取 ServiceProvider
问题描述
有没有一种好方法可以在我们完全设置 DI 容器的地方获取ServiceProvider
或AddOpenIdConnect
配置ClientSecret?(例如在Configure(IApplicationBuilder app)
)
我们从其他地方获取客户端机密,我们喜欢为此使用 DI。
目前我们这样做,但我真的很想删除 services.BuildServiceProvider()
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddOpenIdConnect(AuthenticationScheme, options =>
{
ServiceProvider serviceProvider = services.BuildServiceProvider(); // we like to prevent this
options.ClientSecret = serviceProvider.GetRequiredService<ISecretRetriever>().GetClientSecret();
笔记
对于像OnValidatePrincipal
我们可以从中得到它的事件CookieValidatePrincipalContext.HttpContext.RequestServices
使用services.BuildServiceProvider()
会给出这个警告:
警告“从应用程序代码调用‘BuildServiceProvider’会导致创建一个额外的单例服务副本”
解决方案
身份验证的配置系统使用选项模式。这意味着以下方法将具有与您的问题中显示的方法类似的效果:
services.AddAuthentication()
.AddOpenIdConnect(AuthenticationScheme, options =>
{
// ...
});
services.Configure<OpenIdConnectOptions>(AuthenticationScheme, options =>
{
options.ClientSecret = "ClientSecret";
});
这很有用,因为选项模式支持 DI,使用如下内容:
services.AddOptions<OpenIdConnectOptions>(AuthenticationScheme)
.Configure<ISecretRetriever>((options, secretRetriever) =>
{
options.ClientSecret = secretRetriever.GetClientSecret();
});
要访问Configure
适用于 DI 的方法,您必须首先调用AddOptions
. 在此示例中,Configure
给定了一个类型参数,它表示所需的依赖项。这将作为第二个参数传递到您的配置回调中,位于OpenIdConnectOptions
正在配置的实例之后。
推荐阅读
- hibernate - 如何在没有未经检查的强制转换的情况下在 JPA 标准中执行连接提取?
- javascript - 根据 xAxis 元素单击公开其他数据 - Highcharts.js
- android - 将本机 ios/Android 代码导入 Xamarin 项目
- logical-operators - 如何使用 ScalaTest 执行 OR
- javascript - 如何在 Node.js 中发送真实数据?
- html - Angular Bootstrap 4 Navbar 不会切换和 navbar-dark 问题
- c# - 不能画一条简单的线
- html - 放置 div 块
- spring - Spring Security:自定义 UserDetails 和 GrandtedAuthority 实现
- asp.net-mvc-5 - 为什么我不应该使用 MVC Jsonresult 而不是 apicontroller get 方法