此篇是我记录代码的一个草稿,不是一篇正式的博文,误点的别介意啊。
公司的框架中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();
}
}
}
}