Asp.net Core在Filter中使用依赖注入TypeFilter,ServiceFilter

小伙伴们大家好,相信写过http://asp.net的小伙伴对过滤器(Filter)一定不会陌生,今天我来跟大家分享一下如何在http://asp.net core Filter中实现依赖注入,以及相关的技术细节。废话不多说,我们开始吧。

创建自定义过滤器

先创建一个MVC项目,然后我们创建一个自定义的过滤器

public class MyFilter: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        
        base.OnActionExecuting(context);
    }
}

这里我们没有做任何事,现在需求来了,我们需要过滤器中记录日志,这时候我们就需要注入Logger,代码大致如下。

public class MyFilter: ActionFilterAttribute
{
    private readonly ILogger<MyFilter> _logger;

    public MyFilter(ILogger<MyFilter> logger)
    {
        _logger = logger;
    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation("do something.....");
        base.OnActionExecuting(context);
    }
}

这时候,使用的时候就会报错,很明显构造函数参数不匹配
在这里插入图片描述
这种情况下,直接往里面传参是不行的,那么该如何处理呢?这就引出我们今天的主角,TypeFilterServiceFilter

ServiceFilter

我们先来讲讲ServiceFilter,使用ServiceFilter很简单,我们改造一下controllerfilter的调用,以及在ConfigureServices中进行注册。

注意:这里AddSingleton只是出于演示,您可以根据您的需求自定义您的Filter实例的生命周期。

[ServiceFilter(typeof(MyFilter))]
public IActionResult Index()
{
    return View();
}

在这里插入图片描述

运行一下,我们可以看到已经起作用了。
在这里插入图片描述
ServiceFilter最值得注意的就是需要对您定义的filter进行注册才能使用。

为什么它需要事先注册对应的类型呢?我们研究一下源码就可以得知,它创建实例通是通过IServiceProvider中的GetRequiredService方法实现的,它的Type的实例直接从DI容器中获取。这也许就是它为啥叫ServiceFilter的原因吧。

下面给大家截了一段ServiceFilter的源码
在这里插入图片描述

TypeFilter

TypeFilterServiceFilter比较类似,我们改造一下
在这里插入图片描述
是不是很像,它和ServiceFilter的区别是它不从DI容器中创建实例,所以不需要在ConfigureServices中进行注册就能使用。我们来看一下源码
在这里插入图片描述
实际上,TypeFilter是通过ObjectFactory来创建实例的,ObjectFactoryActivatorUtilities.CreateFactory创建出来的委托,对于没有注册的服务想创建实例,.net core提供的ActivatorUtilities就派上用场了。这么说可能有点抽象,我下面写一个小例子。

public class Employee
{
    private readonly ILogger<Employee> _logger;
    private readonly string _name;

    public Employee(ILogger<Employee>logger,string name)
    {

        _logger = logger;
        _name = name;
    }

    public void Say()
    {
        _logger.LogInformation($"My name is {_name}");
    }
}

我创建了一个Employee类,构造器里有logger也有name,这种情况下,甚至构造器中有更多参数,我们想创造一个Employee的实例是不太容易的,这个时候就该ActivatorUtilities登场了。代码大致如下

var factory = ActivatorUtilities.CreateFactory(typeof(Employee), new Type[] {typeof(string)});
var employee = factory(_provider, new object[] {"Laosiji"}) as Employee;
employee?.Say();

这里我将IServiceProvider传递进去,同时还有额外的name参数,让它帮我们创造出实例,结果如下
在这里插入图片描述

当然这只是一个简单的例子,帮助您理解ObjectFactoryActivatorUtilities之间的关系,如果您感兴趣可以自己深入的研究一下。

说回正题,TypeFilter是每次请求都会创建自定义Filter的实例的,也许有的小伙伴发现它还有别的参数,比如可以这样

  [TypeFilter(typeof(MyFilter),IsReusable = true)]

IsReusable代表是否可以复用,默认值是false,设置为true的时候,可以起到类似单例的效果,但是框架并不能保证它每次都会是单例的,所以您有特殊要求,还是使用ServiceFilter比较妥当,IsReusable就不要动他了。

ServiceFilter vs TypeFilter

文章的最后,我们对他们进行一下总结

  1. ServiceFilterTypeFilter都实现了IFilterFactory
  2. ServiceFilter需要对自定义的Filter进行注册,TypeFilter不需要
  3. ServiceFilterFilter生命周期源自于您如何注册,而TypeFilter每次都会创建一个新的实例
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
依赖注入(Dependency Injection,DI)是一种设计模式,其目的是实现对象之间的解耦,提高代码的可测试性和可维护性。在 .NET Core 依赖注入是一个内置的功能,可以通过 ASP.NET Core 的内置容器或第三方容器库来实现。以下是在 .NET Core 使用依赖注入的步骤: 1. 定义接口和实现类 首先,定义需要注入的接口和实现类。例如: ```csharp public interface IMyService { void DoSomething(); } public class MyService : IMyService { public void DoSomething() { // 实现具体逻辑 } } ``` 2. 注册依赖关系 然后,在应用程序的启动代码,注册接口和实现类之间的依赖关系。例如: ```csharp public void ConfigureServices(IServiceCollection services) { services.AddScoped<IMyService, MyService>(); } ``` 上述代码使用 `AddScoped` 方法将 `IMyService` 接口与 `MyService` 实现类进行了注册。`AddScoped` 方法表示每个请求范围内都会创建一个新的实例。 3. 使用依赖注入 现在,可以在需要使用 `IMyService` 的地方进行依赖注入。例如: ```csharp public class MyController : Controller { private readonly IMyService _myService; public MyController(IMyService myService) { _myService = myService; } public IActionResult Index() { _myService.DoSomething(); return View(); } } ``` 上述代码,`MyController` 类在构造函数注入了 `IMyService` 接口,并在 `Index` 方法使用它。 通过以上步骤,就可以在 .NET Core 使用依赖注入了。值得注意的是,ASP.NET Core 的内置容器支持多种生命周期选项,如 `AddSingleton`、`AddTransient` 和 `AddScoped` 等,可以根据实际需求来选择不同的生命周期选项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值