过滤器注入问题
2019-04-11 14:06 huoit 阅读(751) 评论(1) 收藏 举报过滤器概要
1、过滤器工作顺序


中间件重在影响管道,过滤器重在请求与响应数据交互的环节,如验证错误路由等
2、作用域
三种:Controller、Action、全局;前两种直接加特性就可以了
全局:startup
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.Filters.Add(typeof(SampleActionFilter)); // by type options.Filters.Add(new SampleGlobalActionFilter()); // an instance }); services.AddScoped<AddHeaderFilterWithDi>(); }
3、同步异步
IAsyncActionFilter和IActionFilter;同一个过滤器只能有一种选择,要么同步要么异步,系统会首先检查异步,没有则走同步
public async Task OnActionExecutionAsync
依赖注入两种方法
方法一:使用TypeFilterAttribute或者ServiceFilterAttribute
1、TypeFilterAttribute使用Microsoft.Extensions.DependencyInjection.ObjectFactory实例化类型
public class TypeFilterAttribute : Attribute, IFilterFactory, IOrderedFilter { private ObjectFactory factory; public TypeFilterAttribute([NotNull] Type type) { ImplementationType = type; } public object[] Arguments { get; set; } public Type ImplementationType { get; private set; } public int Order { get; set; } public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider) { if (this.factory == null) { var argumentTypes = Arguments?.Select(a => a.GetType())?.ToArray(); this.factory = ActivatorUtilities.CreateFactory(ImplementationType, argumentTypes ?? Type.EmptyTypes); } return (IFilter)this.factory(serviceProvider, Arguments); } }
使用:
[TypeFilter(typeof(AddHeaderAttribute), Arguments = new object[] { "Author", "Steve Smith (@ardalis)" })] public IActionResult Hi(string name) { return Content($"Hi {name}"); }
2、ServiceFilterAttribute则是暴露IFilterFactory接口,通过系统的DI系统注入,所以需要2个步骤
源码
public class ServiceFilterAttribute : Attribute, IFilterFactory, IOrderedFilter { public ServiceFilterAttribute([NotNull] Type type) { ServiceType = type; } public Type ServiceType { get; private set; } public int Order { get; set; } public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider) { var service = serviceProvider.GetRequiredService(ServiceType); var filter = service as IFilter; if (filter == null) { throw new InvalidOperationException(Resources.FormatFilterFactoryAttribute_TypeMustImplementIFilter( typeof(ServiceFilterAttribute).Name, typeof(IFilter).Name)); } return filter; } }
使用
services.AddScoped<AddHeaderFilterWithDi>();//放入startup才可以使用 [ServiceFilter(typeof(AddHeaderFilterWithDi))]
方法二:自定义依赖注入辅助类
public static class IoC { public static IServiceCollection ServiceCollection { get; set; } private static ServiceProvider ServiceProvider { get; set; } public static void InitializeWith(IServiceCollection serviceDescriptors) { ServiceCollection = serviceDescriptors; ServiceProvider = ServiceCollection.BuildServiceProvider(); } public static void InitializeWith(IServiceCollection serviceDescriptors, IServiceProvider serviceProvider) { ServiceCollection = serviceDescriptors; ServiceProvider = (ServiceProvider)serviceProvider; } public static bool IsExist() { return ServiceCollection != null; } public static T Resolve<T>() { return ServiceProvider.GetService<T>(); } public static IEnumerable<T> ResolveAll<T>() { return ServiceProvider.GetServices<T>(); } public static void Reset() { if (ServiceCollection != null) { ServiceCollection.Clear(); ServiceProvider.Dispose(); } } }
再startup中初始化
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddCors(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); IoC.InitializeWith(services); }
资料:
https://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_4_3-filters.html
1、如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
2、欢迎各位转载,但是未经作者本人同意,转载文章请在文章页面明显位置标明作者和原文连接,否则保留追究法律责任的权利。
作者博客: http://www.cnblogs.com/xmai/
浙公网安备 33010602011771号