Dab*_*oul 9 c# authentication dependency-injection asp.net-core
当我的应用程序启动时,我有一堆模块(module1,module2 ......).对于每个模块,我都有一堆控制器操作:
/myModuleController/module1/action1
/myModuleController/module1/action2
/myModuleController/module2/action1
/myModuleController/module2/action2
…
Run Code Online (Sandbox Code Playgroud)
由于用户可以为每个模块记录一次,我为每个模块部署一个身份验证中间件,这样就可以这样做:
app.UseWhen((context) => context.Request.Path.StartsWithSegments(urlPath), appbuilder =>
{
appbuilder.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieName = cookieName,
…
});
});
Run Code Online (Sandbox Code Playgroud)
所以基本上,在url路径上/myModuleController/module1我有一个中间件加上它的cookie,另一个用于/myModuleController/module2...它有点不寻常我想但它工作正常,我对这种行为很满意.
问题出在这里:我希望能够在运行时添加一个新模块,这意味着能够使用一段代码部署一个新的中间件app.UseWhen(url, app. UseCookieAuthentication(…)).我试着天真地注入IApplicationBuilder app负责添加模块的控制器,但我得到一个例外:
System.InvalidOperationException:尝试激活'AdminController'时无法解析类型'Microsoft.AspNetCore.Builder.IApplicationBuilder'的服务
我的问题是:它应该有效吗?我一定是在某个地方弄错了?或者,你是否清楚我在这里尝试的东西没有机会工作?
你怎么会达到同样的要求?谢谢.
首先我们需要一个服务来保持运行时中间件配置
public class RuntimeMiddlewareService
{
private Func<RequestDelegate, RequestDelegate> _middleware;
private IApplicationBuilder _appBuilder;
internal void Use(IApplicationBuilder app)
=> _appBuilder = app.Use(next => context => _middleware == null ? next(context) : _middleware(next)(context));
public void Configure(Action<IApplicationBuilder> action)
{
var app = _appBuilder.New();
action(app);
_middleware = next => app.Use(_ => next).Build();
}
}
Run Code Online (Sandbox Code Playgroud)
然后添加一些扩展方法来使用它 Startup
public static class RuntimeMiddlewareExtensions
{
public static IServiceCollection AddRuntimeMiddleware(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Singleton)
{
services.Add(new ServiceDescriptor(typeof(RuntimeMiddlewareService), typeof(RuntimeMiddlewareService), lifetime));
return services;
}
public static IApplicationBuilder UseRuntimeMiddleware(this IApplicationBuilder app, Action<IApplicationBuilder> defaultAction = null)
{
var service = app.ApplicationServices.GetRequiredService<RuntimeMiddlewareService>();
service.Use(app);
if (defaultAction != null)
{
service.Configure(defaultAction);
}
return app;
}
}
Run Code Online (Sandbox Code Playgroud)
然后修改你的 Startup
添加到ConfigureServices:
services.AddRuntimeMiddleware(/* ServiceLifetime.Scoped could be specified here if needed */);
Run Code Online (Sandbox Code Playgroud)
添加到运行时指定的中间件应该在的位置Configure。
app.UseRuntimeMiddleware(runtimeApp =>
{
//runtimeApp.Use...
//Configurations here could be replaced during the runtime.
});
Run Code Online (Sandbox Code Playgroud)
最后,您可以从应用程序的其他部分重新配置运行时中间件
//var runtimeMiddlewareService = serviceProvider.GetRequiredService<RuntimeMiddlewareService>();
//Or resolved via constructor.
runtimeMiddlewareService.Configure(runtimeApp =>
{
//runtimeApp.Use...
//Configurations here would override the former ones.
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1381 次 |
| 最近记录: |