dotnetcore / osharp

OSharp是一个基于.Net6.0的快速开发框架,框架对 AspNetCore 的配置、依赖注入、日志、缓存、实体框架、Mvc(WebApi)、身份认证、功能权限、数据权限等模块进行更高一级的自动化封装,并规范了一套业务实现的代码结构与操作流程,使 .Net 框架更易于应用到实际项目开发中。
Apache License 2.0
2.77k stars 748 forks source link

GetAuthInfo 方法获取时间过长, 希望能够优化一下 #227

Closed gmf520 closed 3 years ago

gmf520 commented 3 years ago

GetAuthInfo 方法获取时间过长, 希望能够优化一下

Originally posted by @tegohang in https://github.com/dotnetcore/osharp/issues/168#issuecomment-706459629

gmf520 commented 3 years ago

原先慢的原因,是依赖于数据库查询所有模块-模块的所有功能,还涉及模块树遍历,确实很垃圾

优化思路:

在系统初始化的时候,已经根据最新代码通过IModuleInfoPicker.Pickup()提取了ModuleInfo[]信息,此信息包含了Module树,Module->Function[]的信息,可以缓存复用,解决上面慢的原因 实现如下:

        public string[] GetAuthInfo()
        {
            IServiceProvider provider = HttpContext.RequestServices;
            IModuleHandler moduleHandler = provider.GetRequiredService<IModuleHandler>();
            IFunctionAuthorization functionAuthorization = provider.GetService<IFunctionAuthorization>();
            ModuleInfo[] moduleInfos = moduleHandler.ModuleInfos;

            //先查找出所有有权限的模块
            List<ModuleInfo> authModules = new List<ModuleInfo>();
            foreach (ModuleInfo moduleInfo in moduleInfos)
            {
                bool hasAuth = moduleInfo.DependOnFunctions.All(m => functionAuthorization.Authorize(m, User).IsOk);
                if (moduleInfo.DependOnFunctions.Length == 0 || hasAuth)
                {
                    authModules.Add(moduleInfo);
                }
            }

            List<string> codes = new List<string>();
            foreach (ModuleInfo moduleInfo in authModules)
            {
                string fullCode = moduleInfo.FullCode;
                //模块下边有功能,或者拥有子模块
                if (moduleInfo.DependOnFunctions.Length > 0 
                    || authModules.Any(m => m.FullCode.Length > fullCode.Length && m.FullCode.Contains(fullCode) && m.DependOnFunctions.Length > 0))
                {
                    codes.AddIfNotExist(fullCode);
                }
            }
            return codes.ToArray();
        }