ASP.NET Core如何在ActionFilterAttribute里做依赖注入
点击蓝字
关注我
在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里做依赖注入相关推荐
- .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入
本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样理解控制反转,假设有一个人他有一部A品牌手机,他用手机进行听歌.打 ...
- 控制反转_.NET Core ASP.NET Core Basic 12 控制反转与依赖注入
本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样理解控制反转,假设有一个人他有一部A品牌手机,他用手机进行听歌.打 ...
- ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings
问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...
- 如何用计算机制作统计图,如何在EXCEL里做条形统计图?
如何在EXCEL里做条形统计图?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 如何在EXCEL里做条形统计图? 步骤1 ...
- 避免在 ASP.NET Core 3.0 中为启动类注入服务
本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostin ...
- 五:.net core(.NET 6)使用Autofac实现依赖注入
Autofac的简单使用: 由于将来可能引用很多包,为了保持统一队形,我们再新建一个类库项目Wsk.Core.Package,当做包的引用集合: 删掉Class1,把Wsk.Core.Wsk.Core ...
- core webapi缩略图_在ASP.NET Core Web API 项目里无法访问(wwwroot)下的文件
新建 ASP.NET Core Web API 项目 -- RESTFul 风格 Hello World! 一.创建一个空项目 请查看 新建 .NET Core 项目 -- Hello World! ...
- ASP.NET Core 中如何通过 AuthorizeAttribute 做自定义验证?
咨询区 jltrem: 我想在 ASP.NET Core 中用 authorization 特性实现一个自定义验证,在之前的版本中,我可以用系统提供的 bool AuthorizeCore(HttpC ...
- Asp.net core 3.1利用IHostedService为系统注入自己的主机
IHostedService 这个接口只包含两个成员方法: Task StartAsync(CancellationToken cancellationToken); Task StopAsync(C ...
最新文章
- java中static、final、static final的区别
- mybatisplus自动生成id_mybatisPlus自动代码生成实例(超级简单使用)
- 在Python,Java和Kotlin中标记参数和重载
- 计算机存储器发展历史,存储器及其发展历史与前景(4页)-原创力文档
- Mybatis构建sql语法
- Flink SQL 在快手的扩展和实践
- 图文介绍进程和线程的区别
- Objective-C 常用结构体
- Atitit.你这些项目不都是模板吗?不是原创 集成和整合的方式大总结
- 基于51单片机+LD3320语音模块+SYN6288语音合成——语音识别智能分类垃圾桶
- 用java编写圆锥,java编写圆锥形体积
- TSP旅行商时间复杂度与空间复杂度
- 东北大学计算机BAT,基于BAT-OOPN方法的污染物排放量化模型研究
- 实数系基本定理证明第①波
- 高漫数位板1060PRO 8192级的驱动下载与安装
- 电脑实时监控信息:CPU 内存 GPU使用率在桌面上动态展现
- MySQL语句增加字段,修改字段名,修改类型,修改默认值
- Nginx基础配置和相关知识
- 中国大学MOOC C语言程序设计(大连理工大学) 课后编程题 第十二周题解(个人向仅供参考)
- 【bzoj3573】[Hnoi2014]米特运输
热门文章
- confd_confd + Nacos | 无代码侵入的配置变更管理
- win 7 旗舰版镜像 注入USB3.0 驱动
- 王彪20162321 2016-2017-2 《程序设计与数据结构》第5周学习总结
- eclipse 运行MapReduce程序错误异常汇总(解决Map not fount)
- 博客群发(2)--实现登陆
- 浅谈VS2012单元测试
- 27个赢得别人欣赏的诀窍
- 验证规则构建神器 FluentValidation.md
- Jenkins file一行代码部署.NET程序到K8S
- .NET 6 新特性 WaitAsync