项目架构开发:数据访问层之Cache
數(shù)據(jù)訪問層簡單介紹
數(shù)據(jù)訪問層,提供整個項目的數(shù)據(jù)訪問與持久化功能。在分層系統(tǒng)中所有有關(guān)數(shù)據(jù)訪問、檢索、持久化的任務(wù),最終都將在這一層完成。
來看一個比較經(jīng)典的數(shù)據(jù)訪問層結(jié)構(gòu)圖
大概可以看出如下信息
1、有緩存、日志、異常處理、數(shù)據(jù)CRUD、查詢及數(shù)據(jù)事務(wù)等功能
2、無縫對接如EF、ADO.NET、NH、Dapper等數(shù)據(jù)訪問技術(shù)
3、對外只開放接口層,隱藏具體實現(xiàn),這樣就可以解耦業(yè)務(wù)層與數(shù)據(jù)訪問層
?
今天斗膽通過一個簡單實例來實踐一下,如有不妥的地方,歡迎指正
創(chuàng)建接口層,定義可以提供的一些服務(wù)接口
?
這里我們一個有5種服務(wù)接口,方法的功能就不介紹了,應(yīng)該都能看懂
緩存接口:ICache.cs
1 public interface ICache<T> where T : class 2 { 3 IEnumerable<T> Gets(string key); 4 T Get(string key); 5 bool Sets(string key, IEnumerable<T> value, TimeSpan expiresIn); 6 bool Set(string key, T value, TimeSpan expiresIn); 7 bool Remove(string key); 8 }?
緩存服務(wù)的實現(xiàn)
因為可能支持多種緩存,所以我實現(xiàn)了Web緩存與Redis緩存,這2中緩存分別在項目初期和后期集群中可能會用到
?
我們來看HttpRuntimeCache.cs (還有一種Web緩存HttpContext.Cache,不夠這種只能在Web應(yīng)用使用,所以一般不推薦)
1 public class HttpRuntimeCache<T> : ICache<T> where T : class2 {3 public HttpRuntimeCache()4 {5 6 }7 8 public T Get(string key)9 { 10 if (System.Web.HttpRuntime.Cache[key] == null) 11 { 12 return default(T); 13 } 14 15 return System.Web.HttpRuntime.Cache[key] as T; 16 } 17 18 public bool Set(string key, T value, TimeSpan expiresIn) 19 { 20 Set(key, value, expiresIn.Seconds); 21 return true; 22 } 23 24 public bool Remove(string key) 25 { 26 System.Web.HttpRuntime.Cache.Remove(key); 27 return true; 28 } 29 30 private void Set(string key, object value, int absoluteSeconds) 31 { 32 System.Web.HttpRuntime.Cache.Insert(key, value, null, DateTime.Now.AddSeconds(absoluteSeconds), TimeSpan.FromSeconds(0)); 33 } 34 }?
現(xiàn)在緩存功能已經(jīng)實現(xiàn)了;大家應(yīng)該很容易想到怎麼使用了,比如在業(yè)務(wù)層這樣使用
1 ICache<User> cache = new HttpRuntimeCache<User>(); 2 var user = cache.Get("key");?
其實這樣是不對的,因為這樣的話接口ICache相當于沒什么用處,沒有起到應(yīng)有的作用(隔離具體實現(xiàn))
如果要換另一種緩存實現(xiàn)(比如redis),那還要在所有使用了 new HttpRuntimeCache<User>() 的地方改正過來
這樣的耦合要去掉;有2種方式,通過IOC在實例化的時候依賴注入;另一種就是新建一個基礎(chǔ)設(shè)施層,業(yè)務(wù)層依賴于這一層
因為業(yè)務(wù)層肯定是需要調(diào)用一些Utilities、Helper等類型的工具類,這個應(yīng)該是躲不掉的,再怎么接口隔離也去除不了這點
?
基礎(chǔ)設(shè)施層的實現(xiàn)
?
Cache.cs?
?
1 public sealed class Cache<T> where T : class2 {3 private readonly static ICache<T> cacheProvider;4 5 static Cache()6 {7 cacheProvider = ProviderHelper<T>.GetCacheProvider();8 }9 10 public static IEnumerable<T> Gets(string key) 11 { 12 return cacheProvider.Gets(key); 13 } 14 15 public static T Get(string key) 16 { 17 return cacheProvider.Get(key); 18 } 19 20 public static bool Sets(string key, IEnumerable<T> value, TimeSpan expiresIn) 21 { 22 return cacheProvider.Sets(key, value, expiresIn); 23 } 24 25 public static bool Set(string key, T value, TimeSpan expiresIn) 26 { 27 return cacheProvider.Set(key, value, expiresIn); 28 } 29 30 public static bool Remove(string key) 31 { 32 return cacheProvider.Remove(key); 33 } 34 }?
?ProviderHelper.cs 實現(xiàn)如下圖
?
至此,緩存功能實現(xiàn)完畢,我們新建一個測試項目看看結(jié)果
1 [TestClass]2 public class CacheTest3 {4 [TestMethod]5 public void Set()6 {7 var user = new LoginUser()8 {9 Id = Guid.NewGuid(), 10 LoginName = "LoginName", 11 IsEnabled = 1, 12 Password = "mima1987", 13 CreateTime = DateTime.Now 14 }; 15 16 Cache<LoginUser>.Set("UnitTest3.TestMethod1", user, TimeSpan.FromSeconds(10)); 17 var user2 = Cache<LoginUser>.Get("UnitTest3.TestMethod1"); 18 19 Assert.AreEqual(user.Id, user2.Id); 20 } 21 }?
?
看來沒有什么問題。
?
項目架構(gòu)開發(fā)系列
- 項目架構(gòu)開發(fā):數(shù)據(jù)訪問層之Cache
- 項目架構(gòu)開發(fā):數(shù)據(jù)訪問層之Logger
- 項目架構(gòu)開發(fā):數(shù)據(jù)訪問層之Repository
- 項目架構(gòu)開發(fā):數(shù)據(jù)訪問層之Query
- 項目架構(gòu)開發(fā):數(shù)據(jù)訪問層之UnitOfWork
總結(jié)
以上是生活随笔為你收集整理的项目架构开发:数据访问层之Cache的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 申请信用卡怎么快速下卡
- 下一篇: 可转债中签之后什么时候上市交易?附两种查