分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

【aspnetcore】在filter中使用DI

发布时间:2023-09-06 02:17责任编辑:傅花花关键词:暂无标签

学习和使用aspnetcore,必定绕不开注入,不得不说,这对我这种一直使用webform并且上了年纪的码农来说,真心的不轻松。这不,又遇到问题了:

一个企业微信的项目,用户和部门信息使用redis存储,项目中引入IDistributedCache来获取redis中的数据,

startup.cs 中注册redis缓存,NuGet中引入Microsoft.Extensions.Caching.Redis

services.AddDistributedRedisCache((options) =>{ ???options.Configuration = "127.0.0.1:6379";});

使用方法:

public class WeixinUserUtil{ ???private CacheHelper _cacheHelper; ???public WeixinUserUtil(IDistributedCache cache) ???{ ???????_cacheHelper = new CacheHelper(cache); ???} ???public List<GetMemberResult> All() ???{ ???????var result = _cacheHelper.Get<List<GetMemberResult>>("WeixinUsers"); ???????if (result == null) ???????{ ???????????return Init(); ???????} ???????return result; ???} ???public GetMemberResult Get(string id) ???{ ???????return All().Where(d => d.userid == id).FirstOrDefault(); ???} ???public void Reset() ???{ ???????Init(); ???} ???private List<GetMemberResult> Init() ???{ ???????var token = AccessTokenContainer.TryGetToken(WeixinWorkOptions.CorpId, WeixinWorkOptions.Secret); ???????var result = MailListApi.GetDepartmentMemberInfo(token, 1, 1); ???????if (result.errcode != Senparc.Weixin.ReturnCode_Work.请求成功) ???????{ ???????????throw new Exception("用户列表接口获取失败"); ???????} ???????else ???????{ ???????????_cacheHelper.Set<List<GetMemberResult>>("WeixinUsers", result.userlist); ???????????return result.userlist; ???????} ???}}

现在问题来了,有一个自定义的AuthorizationFilter需要调用WeixinUserUtil的Get方法来获取用户信息进行验证,但是实例化WeixinUserUtil需要IDistributedCache参数,这就尴尬了,我们一般都是在Controller的构造函数中实现注入,在Attribute上咋整呢?

俗话说,办法总比问题多,遇到问题解决问题呗,咱有万能的百度不是。具体过程就不提了,最终发现了两个东东,似乎可以解决这个问题,TypeFilter和ServiceFilter。

这两个Filter的理论知识这里就不提了,反正也没看太明白,直接看用法吧。

public class TestTypeFilter : TypeFilterAttribute ???{ ???????public TestTypeFilter() : base(typeof(TestFilterImpl)) ???????{ ???????} ???????private class TestFilterImpl : IActionFilter ???????{ ???????????private ILogger _log; ???????????public TestFilterImpl(ILoggerFactory loggerFactory) ???????????{ ???????????????_log = loggerFactory.CreateLogger<TestFilterImpl>(); ???????????} ???????????public void OnActionExecuted(ActionExecutedContext context) ???????????{ ???????????????_log.LogDebug("TestTypeFilter执行结束"); ???????????} ???????????public void OnActionExecuting(ActionExecutingContext context) ???????????{ ???????????????_log.LogDebug("开始执行TestTypeFilter"); ???????????} ???????} ???}

  

首先就是定义一个有具体功能的Filter,比如上面的TestFilterImpl(这个命名是跟网上的实例学的),在这个Filter里引入要注入的对象,完成具体功能。

然后再定义一个TypeFilter,继承TypeFilterAttribute,如上面的TestTypeFilter,在构造函数中,把先前定义的Filter当作参数传入给父类,就是这句:

public TestTypeFilter() : base(typeof(TestFilterImpl)){ }

使用起来很简单,直接在Controller或者Action上添加 [TestTypeFilter] 即可。

接下来是ServiceFilter,还是先代码

public class TestServiceAuthorizeFilter : IAuthorizationFilter,, IFilterMetadata{ ???private ILogger logger; ???public TestServiceAuthorizeFilter(ILoggerFactory logger) ???{ ???????this.logger = logger.CreateLogger("MyAttribute"); ???} ???public void OnAuthorization(AuthorizationFilterContext context) ???{ ???????if (!context.HttpContext.User.HasClaim(c => c.Type == ClaimTypes.Role)) ???????{ ???????????context.Result = new RedirectResult("/Login"); ???????} ???}}

  

其实就是定义一个普通Filter,如上面的TestServiceAuthorizeFilter,但是注意一定要加上 IFilterMetadata,事实上这个接口不需要实现任何功能,就是个标记而已。

但到这里并不算完,使用ServiceFilter必须要在Startup.cs 的ConfigureServices中注册

services.AddScoped<TestServiceAuthorizeFilter>();

现在,可以使用这个Filter了,用法如下:

[ServiceFilter(typeof(TestServiceAuthorizeFilter))]

好了,问题解决,没有总结好像挺奇怪的~

结束,谢谢~

【aspnetcore】在filter中使用DI

原文地址:https://www.cnblogs.com/diwu0510/p/9749036.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved