1. 程式人生 > >Cache的封裝和使用,用Cache代替Session

Cache的封裝和使用,用Cache代替Session

ICache 介面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hzb.Utils.Caching
{
    /// <summary>
    /// Cache manager interface
    /// </summary>
    public interface ICache
    {
        /// <summary>
        /// Gets or sets the value associated with the specified key.
/// </summary> /// <typeparam name="T">Type</typeparam> /// <param name="key">The key of the value to get.</param> /// <returns>The value associated with the specified key.</returns> T Get<T>(string key); /// <summary>
/// Adds the specified key and object to the cache. /// </summary> /// <param name="key">key</param> /// <param name="data">Data</param> /// <param name="cacheTime">Cache time</param> void Add(string key, object data, int cacheTime = 30
); /// <summary> /// Gets a value indicating whether the value associated with the specified key is cached /// </summary> /// <param name="key">key</param> /// <returns>Result</returns> bool Contains(string key); /// <summary> /// Removes the value with the specified key from the cache /// </summary> /// <param name="key">/key</param> void Remove(string key); /// <summary> /// Clear all cache data /// </summary> void RemoveAll(); object this[string key] { get; set; } int Count { get; } } }

CacheManager 管理類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hzb.Utils.Caching
{
    public class CacheManager
    {
        private CacheManager()
        { }

        private static ICache cache = null;

        static CacheManager()
        {
            ////

            //可以建立不同的cache物件
            cache = (ICache)Activator.CreateInstance(typeof(MemoryCache));// 這裡可以根據配置檔案來選擇
            //cache = (ICache)Activator.CreateInstance(typeof(CustomerCache));
        }

        #region ICache

        /// <summary>
        /// 獲取快取,假如快取中沒有,可以執行委託,委託結果,新增到快取
        /// </summary>
        /// <typeparam name="T">型別</typeparam>
        /// <param name="key"></param>
        /// <param name="acquire">委託 為null會異常</param>
        /// <param name="cacheTime">快取時間</param>
        /// <returns></returns>
        public static T Get<T>(string key, Func<T> acquire, int cacheTime = 600)
        {
            if (cache.Contains(key))
            {
                return GetData<T>(key);
            }
            else
            {
                T result = acquire.Invoke();//執行委託  獲取委託結果   作為快取值
                cache.Add(key, result, cacheTime);
                return result;
            }
        }

        /// <summary>
        /// 當前快取資料項的個數
        /// </summary>
        public static int Count
        {
            get { return cache.Count; }
        }

        /// <summary>
        /// 如果快取中已存在資料項鍵值,則返回true
        /// </summary>
        /// <param name="key">資料項鍵值</param>
        /// <returns>資料項是否存在</returns>
        public static bool Contains(string key)
        {
            return cache.Contains(key);
        }

        /// <summary>
        /// 獲取快取資料
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetData<T>(string key)
        {
            return cache.Get<T>(key);
        }

        /// <summary>
        /// 新增快取資料。
        /// 如果另一個相同鍵值的資料已經存在,原資料項將被刪除,新資料項被新增。
        /// </summary>
        /// <param name="key">快取資料的鍵值</param>
        /// <param name="value">快取的資料,可以為null值</param>
        public static void Add(string key, object value)
        {
            if (Contains(key))
                cache.Remove(key);
            cache.Add(key, value);
        }

        /// <summary>
        /// 新增快取資料。
        /// 如果另一個相同鍵值的資料已經存在,原資料項將被刪除,新資料項被新增。
        /// </summary>
        /// <param name="key">快取資料的鍵值</param>
        /// <param name="value">快取的資料,可以為null值</param>
        /// <param name="expiratTime">快取過期時間間隔(單位:秒) 預設時間600秒</param>
        public static void Add(string key, object value, int expiratTime = 600)
        {
            cache.Add(key, value, expiratTime);
        }

        /// <summary>
        /// 刪除快取資料項
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            cache.Remove(key);
        }

        /// <summary>
        /// 刪除所有快取資料項
        /// </summary>
        public static void RemoveAll()
        {
            cache.RemoveAll();
        }
        #endregion

    }
}

asp.net 系統快取封裝

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.Caching;
using System.Text.RegularExpressions;

namespace Hzb.Utils.Caching
{
    /// <summary>
    /// Represents a MemoryCacheCache
    /// </summary>
    public partial class MemoryCache : ICache
    {
        public MemoryCache() { }

        protected ObjectCache Cache
        {
            get
            {
                return System.Runtime.Caching.MemoryCache.Default;
            }
        }

        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        public T Get<T>(string key)
        {
            if (Cache.Contains(key))
            {
                return (T)Cache[key];
            }

            else
            {
                return default(T);
            }
        }

        public object Get(string key)
        {
            //int iResult=  Get<Int16>("123");

            return Cache[key];
        }

        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time(unit:minute) 預設30秒</param>
        public void Add(string key, object data, int cacheTime = 30)
        {
            if (data == null)
                return;

            var policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromSeconds(cacheTime);
            Cache.Add(new CacheItem(key, data), policy);
        }

        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        public bool Contains(string key)
        {
            return Cache.Contains(key);
        }

        public int Count { get { return (int)(Cache.GetCount()); } }


        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        public void Remove(string key)
        {
            Cache.Remove(key);
        }

        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        public void RemoveByPattern(string pattern)
        {
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var keysToRemove = new List<String>();

            foreach (var item in Cache)
                if (regex.IsMatch(item.Key))
                    keysToRemove.Add(item.Key);

            foreach (string key in keysToRemove)
            {
                Remove(key);
            }
        }

        /// <summary>
        /// 根據鍵值返回快取資料
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[string key]
        {
            get { return Cache.Get(key); }
            set { Add(key, value); }
        }

        /// <summary>
        /// Clear all cache data
        /// </summary>
        public void RemoveAll()
        {
            foreach (var item in Cache)
                Remove(item.Key);
        }
    }
}

自定義快取

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hzb.Utils.Caching
{
    /// <summary>
    /// 自定義快取類
    /// </summary>
    public class CustomerCache : ICache
    {
        private static Dictionary<string, KeyValuePair<object, DateTime>> DATA = new Dictionary<string, KeyValuePair<object, DateTime>>();

        /// <summary>
        /// 獲取快取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            if (!this.Contains(key))
            {
                return default(T); //defalut t 是返回預設的T,比如引用就是返回null int返回0
            }
            else
            {
                KeyValuePair<object, DateTime> keyValuePair = DATA[key];
                if (keyValuePair.Value < DateTime.Now)//過期
                {
                    this.Remove(key);
                    return default(T);
                }
                else
                {
                    return (T)keyValuePair.Key;
                }
            }
        }

        /// <summary>
        /// 新增快取
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <param name="cacheTime">過期時間 預設30秒 </param>
        public void Add(string key, object data, int cacheTime = 30)
        {
            DATA.Add(key, new KeyValuePair<object, DateTime>(data, DateTime.Now.AddSeconds(cacheTime)));

           // DATA.Add(key, new KeyValuePair<object, DateTime>(data, DateTime.Now.AddMinutes(cacheTime)));
        }

        /// <summary>
        /// 判斷包含
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Contains(string key)
        {
            return DATA.ContainsKey(key);
        }

        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="key"></param>
        public void Remove(string key)
        {
            DATA.Remove(key);
        }

        /// <summary>
        /// 全部刪除
        /// </summary>
        public void RemoveAll()
        {
            DATA = new Dictionary<string, KeyValuePair<object, DateTime>>();
        }

        /// <summary>
        /// 獲取
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[string key]
        {
            get
            {
                return this.Get<object>(key);
            }
            set
            {
                this.Add(key, value);
            }
        }

        /// <summary>
        /// 數量
        /// </summary>
        public int Count
        {
            get
            {
                return DATA.Count(d => d.Value.Value > DateTime.Now);
            }
        }
    }
}

呼叫程式碼 :拿使用者登入做列子

using Hzb.Model;
using Hzb.Model.SysEnum;
using Hzb.PC.Bll.Interface;
using Hzb.Utils.Caching;
using Hzb.Utils.Cookie;
using Hzb.Utils.Regular;
using Hzb.Utils.Secret;
using Hzb.Utils.Session;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Hzb.Web.Controllers
{
    public class AccountController : Controller
    {
        private IBaseBLL<User> IUserBLL = null;

        /// <summary>
        /// 建構函式注入
        /// </summary>
        [InjectionConstructor]
        public AccountController(IBaseBLL<User> userBLL)
        {
            IUserBLL = userBLL;
        }

        /// <summary>
        /// 【檢視】 登陸
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Login(string msg)
        {
            ViewData.Model = msg;
            return View();
        }

        /// <summary>
        /// 【處理程式】 登陸
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult PoccLogin(string username, string password)
        {
            bool b = Validator.IsPhoneNumber(username);

            User model = null;
            if (b)
            {
                model = IUserBLL.DBSet().Where(m => m.Account == username).FirstOrDefault();
            }
            else 
            {
                int _id;
                if (int.TryParse(username, out _id))
                {
                     model = IUserBLL.DBSet().Where(m => m.Id == _id).FirstOrDefault();
                }
            }

            if (model != null)
            {
                password = "hzb_" + password + "_zhonghu";

                if ((UserEnum)model.State == UserEnum.Normal)
                {
                    if (model.Password == MD5Helper.MD5FromString(password))
                    {
                        //新增cookie值
                        CookieHelper.AddSingleValueCookie("key", model.Id.ToString(), DateTime.Now.AddHours(1));
                        //新增快取
                        CacheManager.Add(model.Id.ToString(), model, 3600);
                        //獲取session
                        string returntUrl = SessionHelper.GetSessionString("ReturntUrl");
                        if (!string.IsNullOrEmpty(returntUrl))
                        {
                            return Redirect(returntUrl);
                        }
                        else
                        {
                            UserTypeEnum type = (UserTypeEnum)model.Type;
                            switch (type)
                            {
                                case UserTypeEnum.Owner:
                                    return RedirectToAction("Index", "Home", new { area = "User", id = model.Id });
                                case UserTypeEnum.Company:
                                    return RedirectToAction("Index", "Home", new { area = "Company", id = model.Id });
                                case UserTypeEnum.Designer:
                                    return RedirectToAction("Index", "Home", new { area = "Designer", id = model.Id });
                                case UserTypeEnum.Manager:
                                    return RedirectToAction("Index", "Home", new { area = "Manager", id = model.Id });
                                case UserTypeEnum.Supplier:
                                    return RedirectToAction("Index", "Home", new { area = "Supplier", id = model.Id });
                                default:
                                    return RedirectToAction("CustomerError", "Shared", new { msg = "程式錯誤" });
                            }
                        }
                    }
                    else
                    {
                        return RedirectToAction("Login", new { msg = "密碼錯誤" });

                    }
                }
                else
                {
                    return RedirectToAction("Login", new { msg = "賬號已刪除" });
                }

            }
            else
            {
                return RedirectToAction("Login", new { msg = "賬號不存在" });
            }

        }

        /// <summary>
        /// 【處理程式】 退出
        /// </summary>
        [HttpGet]
        public ActionResult Logout()
        {
            //獲取cookie值
            string cookie_value = CookieHelper.GetSingleValueCookieValue("key");

            //清除快取
            CacheManager.Remove(cookie_value);

            //清除cookie值
            CookieHelper.DelSingleValueCookie(cookie_value);


            return RedirectToAction("Login", "Account");
        }
    }
}

MVC檢驗登陸和許可權的filter


using Hzb.Model;
using Hzb.Utils.Caching;
using Hzb.Utils.Cookie;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Hzb.Web.Utility.Filter
{
    /// <summary>
    /// 檢驗登陸和許可權的filter
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = true)]
    public class AuthorityFilter : AuthorizeAttribute
    {
        /// <summary>
        /// 檢查使用者登入
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //獲取cookie值
            string cookie_value = CookieHelper.GetSingleValueCookieValue("key");
            //獲取快取
            var cacheUser = CacheManager.GetData<User>(cookie_value);

            if (cacheUser == null) 
            {
                HttpContext.Current.Session["ReturntUrl"] = filterContext.RequestContext.HttpContext.Request.RawUrl;
                filterContext.Result = new RedirectResult("/Account/Login");
                return;
            }
            else
            {
                //清除快取
                CacheManager.Remove(cookie_value);
                //重新新增快取
                CacheManager.Add(cookie_value, cacheUser, 3600);
                return;
            }
        }
    }
}

特性AuthorityFilter驗證是否登陸

using Hzb.Model;
using Hzb.Model.SysEnum;
using Hzb.Model.ViewModel;
using Hzb.PC.Bll.Interface;
using Hzb.Utils.Caching;
using Hzb.Utils.Cookie;
using Hzb.Utils.Session;
using Hzb.Web.Utility.Filter;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HzbModel = Hzb.Model;

namespace Hzb.Web.Areas.Company.Controllers
{

    public class HomeController : Controller
    {
        private IUserManagerBll IUserManagerBll = null;

        /// <summary>
        /// 建構函式注入
        /// </summary>
        [InjectionConstructor]
        public HomeController(IUserManagerBll userManagerBll)
        {
            IUserManagerBll = userManagerBll;
        }


        /// <summary>
        /// 【檢視】 首頁
        /// </summary>
        /// <returns></returns>
        [AuthorityFilter]
        public ActionResult Index(int id = 0)
        {
            //獲取cookie
            string cookie_value = CookieHelper.GetSingleValueCookieValue("key");
            //獲取快取
            var obj = CacheManager.GetData<HzbModel.User>(cookie_value);
            if (obj != null) 
            {
                if (obj.Id == id)
                {
                    ViewUser model = IUserManagerBll.GetViewUser(id);
                    ViewData.Model = model;
                    return View();
                }
                else 
                {
                    return Redirect("/Account/Login");
                }
            }
            else 
            {
                return Redirect("/Account/Login");
            }
        }

        /// <summary>
        /// 部分檢視【左側選單】
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Menu(int id)
        {
            ViewData.Model = id;
            return View();
        }
    }
}