ASP.NET 核心的 IAuthorizationFilter 和简单注入器的依赖注入失败
Dependency injection failed with IAuthorizationFilter and Simple Injector for ASP.NET Core
这与 非常相似,但解决方案不适用于 .net core 3.1。
所以,我有 IAuthorizationFilter
:
public class AuthFilter : IAuthorizationFilter
{
private readonly IUserService userService;
public AuthFilter(IUserService userService)
{
this.userService = userService;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
Console.WriteLine("Doing authZZZ: " + userService.DoSomething());
}
}
和简单的服务
public interface IUserService
{
string DoSomething();
}
class UserService : IUserService
{
public string DoSomething()
{
return "Something";
}
}
正在将过滤器和服务注册为:
services.Configure<MvcOptions>(options => options.Filters.Add<AuthFilter>());
...
container.Register<IUserService, UserService>(Lifestyle.Transient);
其他一切,如 example
调用操作时出现异常:
InvalidOperationException: Unable to resolve service for type 'TestSimpleInj.IUserService' while attempting to activate 'TestSimpleInj.AuthFilter'.
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
lambda_method(Closure , IServiceProvider , object[] )
Microsoft.AspNetCore.Mvc.TypeFilterAttribute.CreateInstance(IServiceProvider serviceProvider)
Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.ProvideFilter(FilterProviderContext context, FilterItem filterItem)
Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.OnProvidersExecuting(FilterProviderContext context)
Microsoft.AspNetCore.Mvc.Filters.FilterFactory.CreateUncachedFiltersCore(IFilterProvider[] filterProviders, ActionContext actionContext, List<FilterItem> filterItems)
Microsoft.AspNetCore.Mvc.Filters.FilterFactory.GetAllFilters(IFilterProvider[] filterProviders, ActionContext actionContext)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory+<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)
Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
你的问题的答案实际上几乎在你提到的 中给出了,但你只需要一些小的调整就可以让它在 ASP.NET Core MVC 下工作。
您需要将 AuthorizationFilterProxy<TFilter>
更改为以下内容:
public class AuthorizationFilterProxy<TFilter> : IAuthorizationFilter
where TFilter : class, IAuthorizationFilter
{
private readonly Container Container;
public AuthorizationFilterProxy(Container container) =>
this.Container = container;
public void OnAuthorization(AuthorizationFilterContext context) =>
this.Container.GetInstance<TFilter>().OnAuthorization(context);
}
现在你需要将这个 AuthorizationFilterProxy<TFilter>
挂接到 ASP.NET Core MVC 的管道中,可以按如下方式完成:
services.Configure<MvcOptions>(options => options.Filters.Add(
new AuthorizationFilterProxy<AuthFilter>(container)));
container.Register<AuthFilter>();
这也非常类似于向 ASP.NET MVC 添加全局过滤器,如所引用的问题所示。
这会将 AuthorizationFilterProxy<AuthFilter>
添加到 MVC 过滤器列表中,代理会将调用转发给简单注入器。 AuthFilter
现在已从 Simple Injector 及其 IUserService
依赖项中解决。
这与
所以,我有 IAuthorizationFilter
:
public class AuthFilter : IAuthorizationFilter
{
private readonly IUserService userService;
public AuthFilter(IUserService userService)
{
this.userService = userService;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
Console.WriteLine("Doing authZZZ: " + userService.DoSomething());
}
}
和简单的服务
public interface IUserService
{
string DoSomething();
}
class UserService : IUserService
{
public string DoSomething()
{
return "Something";
}
}
正在将过滤器和服务注册为:
services.Configure<MvcOptions>(options => options.Filters.Add<AuthFilter>());
...
container.Register<IUserService, UserService>(Lifestyle.Transient);
其他一切,如 example
调用操作时出现异常:
InvalidOperationException: Unable to resolve service for type 'TestSimpleInj.IUserService' while attempting to activate 'TestSimpleInj.AuthFilter'.
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
lambda_method(Closure , IServiceProvider , object[] )
Microsoft.AspNetCore.Mvc.TypeFilterAttribute.CreateInstance(IServiceProvider serviceProvider)
Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.ProvideFilter(FilterProviderContext context, FilterItem filterItem)
Microsoft.AspNetCore.Mvc.Filters.DefaultFilterProvider.OnProvidersExecuting(FilterProviderContext context)
Microsoft.AspNetCore.Mvc.Filters.FilterFactory.CreateUncachedFiltersCore(IFilterProvider[] filterProviders, ActionContext actionContext, List<FilterItem> filterItems)
Microsoft.AspNetCore.Mvc.Filters.FilterFactory.GetAllFilters(IFilterProvider[] filterProviders, ActionContext actionContext)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory+<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)
Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
你的问题的答案实际上几乎在你提到的
您需要将 AuthorizationFilterProxy<TFilter>
更改为以下内容:
public class AuthorizationFilterProxy<TFilter> : IAuthorizationFilter where TFilter : class, IAuthorizationFilter { private readonly Container Container; public AuthorizationFilterProxy(Container container) => this.Container = container; public void OnAuthorization(AuthorizationFilterContext context) => this.Container.GetInstance<TFilter>().OnAuthorization(context); }
现在你需要将这个 AuthorizationFilterProxy<TFilter>
挂接到 ASP.NET Core MVC 的管道中,可以按如下方式完成:
services.Configure<MvcOptions>(options => options.Filters.Add( new AuthorizationFilterProxy<AuthFilter>(container))); container.Register<AuthFilter>();
这也非常类似于向 ASP.NET MVC 添加全局过滤器,如所引用的问题所示。
这会将 AuthorizationFilterProxy<AuthFilter>
添加到 MVC 过滤器列表中,代理会将调用转发给简单注入器。 AuthFilter
现在已从 Simple Injector 及其 IUserService
依赖项中解决。