WebEnh

.net7 mvc jquery bootstrap json 学习中 第一次学PHP,正在研究中。自学进行时... ... 我的博客 https://enhweb.github.io/ 不错的皮肤:darkgreentrip,iMetro_HD
随笔 - 1079, 文章 - 1, 评论 - 75, 阅读 - 174万
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

ASP.NET Core中的ActionFilter与DI

Posted on   WebEnh  阅读(433)  评论(0编辑  收藏  举报

一、简介

  前几篇文章都是讲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的创建过程。

  2.1 IFilterFactory接口定义

public interface IFilterFactory : IFilter
{
    IFilter CreateInstance([NotNull] IServiceProvider serviceProvider);
}

 

  我们想要创建一个Filter Attribute并需要依赖注入的话一般想要的代码为:

复制代码
复制代码
public class FilterClass : ActionFilterAttribute  
{
  public FilterClass(IDependency1 dependency1, IDependency2 dependency2)
  {
    // ...use dependencies
  }
}
复制代码
复制代码

 

  ASP.NET Core MVC中为我们提供了两种简单的IFilterFactory ServiceFilterAttribute 和 TypeFilterAttribute 。来个例子看看怎么使用。

复制代码
复制代码
public class HomeController: Controller  
{
    [TypeFilter(typeof(FilterClass))]
    [ServiceFilter(typeof(FilterClass))]
    public IActionResult Index()
    {
        return View();
    }
}
复制代码
复制代码

  2.2 ServiceFilterAttribute 

   其实看到名字,有些朋友就能想到了,它是基于依赖注入的一个IFilterFactory,Service这个词强化了它是一个通过获取服务来实现依赖注入的,大家想到了什么?是不是GetService()? 没错,其实它的机制就是这个。

     要使用ServiceFilter就必须在依赖注入容器里注册对应的类型,比如下面的例子就要先将FilterClass类型注册到IOC容器里。

public void ConfigureServices(IServiceCollection services)
{
      services.AddSingleton<FilterClass>();
 
      services.AddMvc()
}

  当然如果FilterClass类型的构造器需要注入类型时,也需要在IOC容器里进行注册才可以使用。

  我们来看下ServiceFilterAttribute的源代码:

复制代码
复制代码
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

   当然你也可以选择使用这个类似于ServiceFilter过滤器的TypeFilter过滤器,它也同样实现了IFilterFactory接口,并可以通过它创建出可使用依赖注入的过滤器来。之所以叫TypeFilter就是因为它并不需要在依赖注入容器里注册类型就能创建出过滤器,  我们来看下它的代码:

复制代码
复制代码
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);
    }
}
复制代码
复制代码

三、结语

  相信看过上一篇文章的朋友都注意到了ServiceProviderActivatorUtilities 的不同,本文中的ServiceFilterAttribute和 TypeFilterAttribute 原理上也是通过它们来创建Filter的,所以使用场景就看大家如何来使用。其实最近看.NET Core的源代码,看到的到处都是接口、工厂使用依赖注入形成扩展点的例子,其实微软以前代码的扩展点也挺多的,只是API并不那么开放,ASP.NET Core中我们看到了一个"开放"的框架。

 

  GitHub:https://github.com/maxzhang1985/YOYOFx  如果觉还可以请Star下, 欢迎一起交流。

 

  .NET Core 开源学习群: 214741894  

 

 
0
0
 
« 上一篇: 查看.NET Core源代码通过Autofac实现依赖注入到Controller属性
» 下一篇: 细说ASP.NET Core静态文件的缓存方式
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

了解更多