点击蓝字

关注我

在ASP.NET Core里,我们可以使用构造函数注入很方便地对Controller,ViewComponent等部件做依赖注入。但是如何给过滤器ActionFilterAttribute也用上构造函数注入呢?

问题

我的博客系统里有个用来删除订阅文件缓存的ActionFilter,想要在发生异常的时候记录日志。我的博客用的日志组件是NLog,因此不使用依赖注入的话,就直接使用LogManager.GetCurrentClassLogger()获得一个Logger的实例。整个过滤器的代码如下:

public class DeleteSubscriptionCache : ActionFilterAttribute

{

private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

public override void OnActionExecuted(ActionExecutedContext context)

{

base.OnActionExecuted(context);

DeleteSubscriptionFiles();

}

private void DeleteSubscriptionFiles()

{

try

{

// ...

}

catch (Exception e)

{

Logger.Error(e, "Error Delete Subscription Files");

}

}

}

然后在Action上去使用,和经典的ASP.NET MVC一样

[Authorize]

[HttpPost, ValidateAntiForgeryToken, DeleteSubscriptionCache]

[Route("manage/edit")]

public IActionResult Edit(PostEditModel model)

这当然可以没有问题的运行,但写代码最重要的就是逼格,这个代码耦合了NLog,而我的博客系统里其他地方早就在用ASP.NET Core的ILogger接口了。如果哪天日志组件不再用NLog了,那么这个地方的代码就得改,而使用ILogger接口的代码就不需要动。虽然这种情况是绝对不会发生的,但是写代码一定要有追求,尽可能过度设计,才能不被人鄙视,然后才能面试造航母,工作拧螺丝。因此我决定把日志组件用依赖注入的方式安排一下。

改造过滤器

方法和在Controller中使用依赖注入完全一样,我们使用构造函数注入ILogger<DeleteSubscriptionCache>类型。于是代码变成了这样:

public class DeleteSubscriptionCache : ActionFilterAttribute

{

protected readonly ILogger<DeleteSubscriptionCache> Logger;

    public DeleteSubscriptionCache(ILogger<DeleteSubscriptionCache> logger)

    {

        Logger = logger;

    }

public override void OnActionExecuted(ActionExecutedContext context)

{

base.OnActionExecuted(context);

DeleteSubscriptionFiles();

}

private void DeleteSubscriptionFiles()

{

try

{

// ...

}

catch (Exception e)

{

Logger.LogError(e, "Error Delete Subscription Files");

}

}

}

但是问题来了,这样的话我们是没法在Action上无脑使用了,因为构造函数要求传参。如果要自己new一个的话,装逼就失败了。我们来看看正确的解决方法~

ServiceFilter

其实ASP.NET Core里,我们可以使用ServiceFilter来完成这个需求。它也是一种Attribute,可以作用在Action上。位于Microsoft.AspNetCore.Mvc.Core程序集里,定义如下:

// A filter that finds another filter in an System.IServiceProvider.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]

public class ServiceFilterAttribute : Attribute, IFilterFactory, IFilterMetadata, IOrderedFilter

{

public ServiceFilterAttribute(Type type);

public int Order { get; set; }

public Type ServiceType { get; }

public bool IsReusable { get; set; }

public IFilterMetadata CreateInstance(IServiceProvider serviceProvider);

}

ServiceFilter允许我们解析一个已经添加到IoC容器里的服务,因此我们需要把DeleteSubscriptionCache注册一下:

services.AddScoped<DeleteSubscriptionCache>();

然后就能直接使用了:

[Authorize]

[HttpPost, ValidateAntiForgeryToken]

[ServiceFilter(typeof(DeleteSubscriptionCache))]

[Route("manage/edit")]

public IActionResult Edit(PostEditModel model)

运行时发现ILogger已经能被实例化了,完美!

参考资料:

https://stackoverflow.com/questions/36109052/inject-service-into-action-filter/36109690

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2

ASP.NET Core如何在ActionFilterAttribute里做依赖注入相关推荐

  1. .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入

    本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样理解控制反转,假设有一个人他有一部A品牌手机,他用手机进行听歌.打 ...

  2. 控制反转_.NET Core ASP.NET Core Basic 12 控制反转与依赖注入

    本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样理解控制反转,假设有一个人他有一部A品牌手机,他用手机进行听歌.打 ...

  3. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

  4. 如何用计算机制作统计图,如何在EXCEL里做条形统计图?

    如何在EXCEL里做条形统计图?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 如何在EXCEL里做条形统计图? 步骤1 ...

  5. 避免在 ASP.NET Core 3.0 中为启动类注入服务

    本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostin ...

  6. 五:.net core(.NET 6)使用Autofac实现依赖注入

    Autofac的简单使用: 由于将来可能引用很多包,为了保持统一队形,我们再新建一个类库项目Wsk.Core.Package,当做包的引用集合: 删掉Class1,把Wsk.Core.Wsk.Core ...

  7. core webapi缩略图_在ASP.NET Core Web API 项目里无法访问(wwwroot)下的文件

    新建 ASP.NET Core Web API 项目 -- RESTFul 风格 Hello World! 一.创建一个空项目 请查看 新建 .NET Core 项目 -- Hello World!  ...

  8. ASP.NET Core 中如何通过 AuthorizeAttribute 做自定义验证?

    咨询区 jltrem: 我想在 ASP.NET Core 中用 authorization 特性实现一个自定义验证,在之前的版本中,我可以用系统提供的 bool AuthorizeCore(HttpC ...

  9. Asp.net core 3.1利用IHostedService为系统注入自己的主机

    IHostedService 这个接口只包含两个成员方法: Task StartAsync(CancellationToken cancellationToken); Task StopAsync(C ...

最新文章

  1. java中static、final、static final的区别
  2. mybatisplus自动生成id_mybatisPlus自动代码生成实例(超级简单使用)
  3. 在Python,Java和Kotlin中标记参数和重载
  4. 计算机存储器发展历史,存储器及其发展历史与前景(4页)-原创力文档
  5. Mybatis构建sql语法
  6. Flink SQL 在快手的扩展和实践
  7. 图文介绍进程和线程的区别
  8. Objective-C 常用结构体
  9. Atitit.你这些项目不都是模板吗?不是原创  集成和整合的方式大总结
  10. 基于51单片机+LD3320语音模块+SYN6288语音合成——语音识别智能分类垃圾桶
  11. 用java编写圆锥,java编写圆锥形体积
  12. TSP旅行商时间复杂度与空间复杂度
  13. 东北大学计算机BAT,基于BAT-OOPN方法的污染物排放量化模型研究
  14. 实数系基本定理证明第①波
  15. 高漫数位板1060PRO 8192级的驱动下载与安装
  16. 电脑实时监控信息:CPU 内存 GPU使用率在桌面上动态展现
  17. MySQL语句增加字段,修改字段名,修改类型,修改默认值
  18. Nginx基础配置和相关知识
  19. 中国大学MOOC C语言程序设计(大连理工大学) 课后编程题 第十二周题解(个人向仅供参考)
  20. 【bzoj3573】[Hnoi2014]米特运输

热门文章

  1. confd_confd + Nacos | 无代码侵入的配置变更管理
  2. win 7 旗舰版镜像 注入USB3.0 驱动
  3. 王彪20162321 2016-2017-2 《程序设计与数据结构》第5周学习总结
  4. eclipse 运行MapReduce程序错误异常汇总(解决Map not fount)
  5. 博客群发(2)--实现登陆
  6. 浅谈VS2012单元测试
  7. 27个赢得别人欣赏的诀窍
  8. 验证规则构建神器 FluentValidation.md
  9. Jenkins file一行代码部署.NET程序到K8S
  10. .NET 6 新特性 WaitAsync