[英]How to access a service added to DI container from inside Asp.Net Core's ConfigureServices method
The code sample below is from Asp.Net Core ConfigureServices
method in Startup.cs.下面的代码示例来自 Startup.cs 中的 Asp.Net Core
ConfigureServices
方法。
I am first registering a singleton service called AppState
.我首先注册了一个名为
AppState
的 singleton 服务。 Subsequent to that, I am configuring OpenIdConnect, and inside the OnTokenValidated
lambda, I need to access the AppState
service that I just registered in the DI container up above.之后,我正在配置 OpenIdConnect,在
OnTokenValidated
lambda 中,我需要访问我刚刚在上面的 DI 容器中注册的AppState
服务。
What is the most elegant way of accessing the AppState
service instance?访问
AppState
服务实例最优雅的方式是什么?
I would prefer to not call services.BuildServiceProvider()
inside the ConfigureServices
method if at all possible.如果可能的话,我宁愿不要在
ConfigureServices
方法中调用services.BuildServiceProvider()
。
services.AddSingleton<AppState>();
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
//How to get access to instance of AppState,
//which was added to DI container up above
AppState appState = //{get from DI somehow};
appState.DoSomething();
}
};
});
EDIT: Using the answer below, I edited the code like so, but I can confirm that the OnTokenValidated event is not firing, as opposed to the code above in my original question, which does fire:编辑:使用下面的答案,我像这样编辑了代码,但我可以确认 OnTokenValidated 事件没有触发,而不是我原来的问题中的上面的代码,它确实触发了:
services.AddOptions<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme)
.Configure<IServiceScopeFactory>((options, sp) => {
using (var scope = sp.CreateScope())
{
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
var appState = scope.ServiceProvider.GetRequiredService<AppState>();
await appState.Dosomething();
}
};
}
});
Use the TokenValidatedContext
to get access to the current request service provider and resolve the service使用
TokenValidatedContext
访问当前请求服务提供者并解析服务
services
.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options => {
options.Events = new OpenIdConnectEvents {
OnTokenValidated = async ctx => {
//Get access to instance of AppState,
//which was added to DI container up above
AppState appState = ctx.HttpContext.RequestServices
.GetRequiredService<AppState>();
await appState.DoSomething();
//...
}
};
});
You can access the DI service from the event context:您可以从事件上下文访问 DI 服务:
services.AddSingleton<AppState>();
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
var appState = (AppState)ctx.HttpContext.RequestServices.GetService(typeof(AppState));
appState.DoSomething();
}
};
});
Calling services.Configure<T>
, adds an IConfigureOptions<T>
to the service container that calls your action method;调用
services.Configure<T>
,将IConfigureOptions<T>
添加到调用您的操作方法的服务容器中; https://github.com/aspnet/Options/blob/master/src/Microsoft.Extensions.Options/OptionsServiceCollectionExtensions.cs#L72 https://github.com/aspnet/Options/blob/master/src/Microsoft.Extensions.Options/OptionsServiceCollectionExtensions.cs#L72
You can define your own implementation of IConfigureOptions<T>
and inject any service you like.您可以定义自己的
IConfigureOptions<T>
实现并注入您喜欢的任何服务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.