此篇是我记录代码的一个草稿,不是一篇正式的博文,误点的别介意啊。
公司的框架中Cache实现文件:
(1)CacheUtil.cs
using System.Collections.Generic; using System.Linq; using Modules; using ORM; namespace Console { public static class CacheUtil { private const string LoginUserKey = "CacheKey-LoginUserCacheKey"; private const string SerializedLimitedMenusKey = "CacheKey-SerializedLimitedMenusKey"; private const string AllFuncsKey = "CacheKey-AllFuncsKey"; private const string LimitedFuncsKey = "CacheKey-LimitedFuncsKey"; /// <summary> /// 获取或设置当前登录用户 /// </summary> public static User LoginUser { get { return WebCache.GetCache(LoginUserKey) as User; } set { WebCache.SetCache(LoginUserKey, value); } } /// <summary> /// 获取用户是否登录的状态 /// </summary> public static bool IsLogin { get { return LoginUser != null; } } /// <summary> /// 获取有权限的菜单 /// </summary> private static IList<Menu> GetLimitedMenus() { var isAdmin = LoginUser.IsAdmin; using (var context = new MyDbContext()) { IQueryable<Menu> menus = context.Menus; if (isAdmin) return menus.OrderByDescending(x => x.OrderNumber).ToList(); var menuIds = (from ur in context.UserRoles join rm in context.RoleMenus on ur.RoleId equals rm.RoleId where ur.UserId == LoginUser.Id select rm.MenuId); menus = menus.Where(x => menuIds.Contains(x.Id)); return menus.OrderByDescending(x => x.OrderNumber).ToList(); } } private static IList<Menu> GetSerializedLimitedMenus() { var list = new List<Menu>(); var limitedMenus = GetLimitedMenus(); for (var i = limitedMenus.Count - 1; i >= 0; i--) { if (limitedMenus[i].ParentId.HasValue) continue; list.Add(limitedMenus[i]); limitedMenus.RemoveAt(i); } foreach (var item in list) { FeatchChildren(item, limitedMenus); } return list; } private static void FeatchChildren(Menu menu, IList<Menu> menus) { if (!menus.Any()) return; for (var i = menus.Count - 1; i >= 0; i--) { if (!menus[i].ParentId.Equals(menu.Id)) continue; menu.Children.Add(menus[i]); menus.RemoveAt(i); } if (!menu.Children.Any()) return; foreach (var child in menu.Children) { FeatchChildren(child, menus); } } /// <summary> /// 获取经过序列化的有权限的菜单 /// </summary> public static IList<Menu> SerializedLimitedMenus { get { var serializedLimitedMenus = WebCache.GetCache(SerializedLimitedMenusKey) as IList<Menu>; if (serializedLimitedMenus != null) return serializedLimitedMenus; serializedLimitedMenus = GetSerializedLimitedMenus(); WebCache.SetCache(SerializedLimitedMenusKey, serializedLimitedMenus); return serializedLimitedMenus; } } /// <summary> /// 获取拥有权限的菜单上的所有功能 /// </summary> public static IList<Func> AllFuncs { get { var allFuncs = WebCache.GetCache(AllFuncsKey) as IList<Func>; if (allFuncs != null) return allFuncs; using (var context = new MyDbContext()) { allFuncs = context.Funcs.ToList().Where(x => !string.IsNullOrWhiteSpace(x.FuncCode)).ToList(); WebCache.SetCache(AllFuncsKey, allFuncs); } return allFuncs; } } /// <summary> /// 拥有权限的功能列表 /// </summary> public static IList<Func> LimitedFuncs { get { var limitedFuncs = WebCache.GetCache(LimitedFuncsKey) as IList<Func>; if (limitedFuncs != null) return limitedFuncs; var isAdmin = LoginUser.IsAdmin; using (var context = new MyDbContext()) { IQueryable<Func> funcs = context.Funcs; if (!isAdmin) { var funcIds = (from ur in context.UserRoles join rm in context.RoleFuncs on ur.RoleId equals rm.RoleId where ur.UserId == LoginUser.Id select rm.FuncId); funcs = funcs.Where(x => funcIds.Contains(x.Id)); } limitedFuncs = funcs.ToList(); } WebCache.SetCache(LimitedFuncsKey, limitedFuncs); return limitedFuncs; } } public static IList<Func> GetForbiddenFuncs() { return LoginUser == null ? AllFuncs : AllFuncs.Where(x => LimitedFuncs.All(y => y.Id != x.Id)).ToList(); } } }
(2)WebCache.cs(核心)
using System; using System.Web; using System.Web.Caching; using Common; namespace Console { /// <summary> /// 缓存操作类 /// </summary> public class WebCache { #region 私有变量 private const string UserIdentifyKey = "CacheUserIdentifyKey"; #endregion #region 公共方法 /// <summary> /// 获取缓存 /// </summary> /// <param name="key">键</param> /// <returns></returns> public static object GetCache(string key) { return GetUserCache()[key]; } /// <summary> /// 设置缓存 /// </summary> /// <param name="key">键</param> /// <param name="value">值</param> /// <returns></returns> public static bool SetCache(string key, object value) { try { var userCache = GetUserCache(); userCache[key] = value; return true; } catch { return false; } } /// <summary> /// 清空缓存 /// </summary> /// <returns></returns> public static bool ClearCache() { try { // 只清除缓存内容 // GetUserCache().Clear(); // 直接从Cache里移除 var identify = GetUserIdentify(); HttpContext.Current.Cache.Remove(identify); return true; } catch { return false; } } /// <summary> /// 移除缓存 /// </summary> /// <param name="key">键</param> /// <returns></returns> public static bool RemoveCache(string key) { try { GetUserCache().Remove(key); return true; } catch { return false; } } #endregion #region 私有方法 private static string GetUserIdentify() { if (HttpContext.Current.Session[UserIdentifyKey] != null) return HttpContext.Current.Session[UserIdentifyKey].ToString(); var identify = Guid.NewGuid().ToString(); HttpContext.Current.Session[UserIdentifyKey] = identify; return identify; } private static UserCache GetUserCache() { var identify = GetUserIdentify(); if (HttpContext.Current.Cache.Get(identify) == null) { HttpContext.Current.Cache.Insert(identify, new UserCache(), null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 20, 0), CacheItemPriority.High, CacheRemovedCallback); } return HttpContext.Current.Cache.Get(identify) as UserCache; } /// <summary> /// 缓存被移除时触发 /// </summary> /// <param name="key">被移除的缓存的key</param> /// <param name="value">被移除的缓存的值</param> /// <param name="reason">移除原因</param> private static void CacheRemovedCallback(string key, object value, CacheItemRemovedReason reason) { // 缓存被移除时执行的操作 // 如果是手动移除,则不处理 //if (reason == CacheItemRemovedReason.Removed) // return; // 此处访问页面会报错,暂时注释掉 // ShowNotification(MessageType.Warning, "警告", "由于您太久没操作页面已过期,请重新登录!", true); } #endregion } }
(3)UserCache.cs
using System.Collections.Generic; namespace Common { public class UserCache { private readonly Dictionary<string, object> cacheDictionary = new Dictionary<string, object>(); private readonly object lockObj = new object(); /// <summary> /// 索引器 /// </summary> /// <param name="key">key</param> /// <returns>缓存对象</returns> public object this[string key] { get { lock (lockObj) { return cacheDictionary.ContainsKey(key) ? cacheDictionary[key] : null; } } set { lock(lockObj) { if (cacheDictionary.ContainsKey(key)) { cacheDictionary[key] = value; } else { cacheDictionary.Add(key, value); } } } } public void Remove(string key) { lock (lockObj) { if(cacheDictionary.ContainsKey(key)) { cacheDictionary.Remove(key); } } } public void Clear() { lock(lockObj) { cacheDictionary.Clear(); } } } }