ASP.NET Core-ActionFilter实现依赖注入(ServiceFilterAttribute 、TypeFilterAttribute) 【转】
2021-05-01 05:28
标签:spn orm 原理 ref 机制 dep common filter not 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或抽象工厂来扩展功能,就如IControllerActivator这样的功能点在上篇文章(查看.NET Core源代码通过Autofac实现依赖注入到Controller属性)中也提到了,今天我们主要介绍一个大类似的扩展点,ASP.NET Core MVC中为我们提供了新的机制为Action Filters(也就是过滤器)进行依赖注入的扩展。 在ASP.NET Core MVC中,框架中为我们提供了类型为 IFilter 的 Attributes 来装饰Action,用于拦截Action请求,这有在以前的版本中就有了,但是如果我们想结合依赖注入使用的话要使用IFilterFactory接口来扩展Action Filter的创建过程。 我们想要创建一个Filter Attribute并需要依赖注入的话一般想要的代码为: ASP.NET Core MVC中为我们提供了两种简单的IFilterFactory : ServiceFilterAttribute 和 TypeFilterAttribute 。来个例子看看怎么使用。 其实看到名字,有些朋友就能想到了,它是基于依赖注入的一个IFilterFactory,Service这个词强化了它是一个通过获取服务来实现依赖注入的,大家想到了什么?是不是GetService()? 没错,其实它的机制就是这个。 要使用ServiceFilter就必须在依赖注入容器里注册对应的类型,比如下面的例子就要先将FilterClass类型注册到IOC容器里。 当然如果FilterClass类型的构造器需要注入类型时,也需要在IOC容器里进行注册才可以使用。 我们来看下ServiceFilterAttribute的源代码: 当然你也可以选择使用这个类似于ServiceFilter过滤器的TypeFilter过滤器,它也同样实现了IFilterFactory接口,并可以通过它创建出可使用依赖注入的过滤器来。之所以叫TypeFilter就是因为它并不需要在依赖注入容器里注册类型就能创建出过滤器, 我们来看下它的代码: 相信看过上一篇文章的朋友都注意到了ServiceProvider和ActivatorUtilities 的不同,本文中的ServiceFilterAttribute和 TypeFilterAttribute 原理上也是通过它们来创建Filter的,所以使用场景就看大家如何来使用。其实最近看.NET Core的源代码,看到的到处都是接口、工厂使用依赖注入形成扩展点的例子,其实微软以前代码的扩展点也挺多的,只是API并不那么开放,ASP.NET Core中我们看到了一个"开放"的框架。 ASP.NET Core-ActionFilter实现依赖注入(ServiceFilterAttribute 、TypeFilterAttribute) 【转】 标签:spn orm 原理 ref 机制 dep common filter not 原文地址:https://www.cnblogs.com/fanfan-90/p/12147989.html一、简介
二、过滤器依赖注入
2.1 IFilterFactory接口定义
public interface IFilterFactory : IFilter
{
IFilter CreateInstance([NotNull] IServiceProvider serviceProvider);
}
public class FilterClass : ActionFilterAttribute
{
public FilterClass(IDependency1 dependency1, IDependency2 dependency2)
{
// ...use dependencies
}
}
public class HomeController: Controller
{
[TypeFilter(typeof(FilterClass))]
[ServiceFilter(typeof(FilterClass))]
public IActionResult Index()
{
return View();
}
}
2.2 ServiceFilterAttribute
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton
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;
}
}
2.3 TypeFilterAttribute
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);
}
}
三、结语
上一篇:js之原型链&继承
下一篇:d3.js制作条形时间范围选择器
文章标题:ASP.NET Core-ActionFilter实现依赖注入(ServiceFilterAttribute 、TypeFilterAttribute) 【转】
文章链接:http://soscw.com/index.php/essay/80726.html