码迷,mamicode.com
首页 > Web开发 > 详细

【aspnetcore】在filter中使用DI

时间:2018-10-07 00:04:26      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:except   开始   http   else   reset   contain   nbsp   方法   token   

学习和使用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

标签:except   开始   http   else   reset   contain   nbsp   方法   token   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!