数据访问层,提供整个项目的数据访问与持久化功能。在分层系统中所有有关数据访问、检索、持久化的任务,最终都将在这一层完成。
来看一个比较经典的数据访问层结构图
大概可以看出如下信息
1、有缓存、日志、异常处理、数据 CRUD、查询及数据事务等功能
2、无缝对接如 EF、ADO.NET、NH、Dapper 等数据访问技术
3、对外只开放接口层,隐藏具体实现,这样就可以解耦业务层与数据访问层
今天斗胆通过一个简单实例来实践一下,如有不妥的地方,欢迎指正
这里我们一个有 5 种服务接口,方法的功能就不介绍了,应该都能看懂
缓存接口:ICache.cs
- 1 public interface ICache where T : class
- 2 {
- 3 IEnumerable Gets(string key);
- 4 T Get(string key);
- 5 bool Sets(string key, IEnumerable value, TimeSpan expiresIn);
- 6 bool Set(string key, T value, TimeSpan expiresIn);
- 7 bool Remove(string key);
- 8 }
因为可能支持多种缓存,所以我实现了 web 缓存与 Redis 缓存,这 2 中缓存分别在项目初期和后期集群中可能会用到
我们来看 HttpRuntimeCache.cs (还有一种 Web 缓存 HttpContext.Cache,不够这种只能在 Web 应用使用,所以一般不推荐)
- 1 public class HttpRuntimeCache : ICache where T : class
- 2 {
- 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 }
现在缓存功能已经实现了;大家应该很容易想到怎麼使用了,比如在业务层这样使用
- 1 ICache cache = new HttpRuntimeCache();
- 2
- var user = cache.Get("key");
其实这样是不对的,因为这样的话接口 ICache 相当于没什么用处,没有起到应有的作用(隔离具体实现)
如果要换另一种缓存实现(比如 redis),那还要在所有使用了 new HttpRuntimeCache<User>() 的地方改正过来
这样的耦合要去掉;有 2 种方式,通过 IOC 在实例化的时候依赖注入;另一种就是新建一个基础设施层,业务层依赖于这一层
因为业务层肯定是需要调用一些 Utilities、Helper 等类型的工具类,这个应该是躲不掉的,再怎么接口隔离也去除不了这点
Cache.cs
- 1 public sealed class Cache where T : class
- 2 {
- 3 private readonly static ICache cacheProvider;
- 4
- 5 static Cache()
- 6 {
- 7 cacheProvider = ProviderHelper.GetCacheProvider();
- 8 }
- 9
- 10 public static IEnumerable 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 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 实现如下图
至此,缓存功能实现完毕,我们新建一个测试项目看看结果
- 1 [TestClass]
- 2 public class CacheTest
- 3 {
- 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.Set("UnitTest3.TestMethod1", user, TimeSpan.FromSeconds(10));
- 17 var user2 = Cache.Get("UnitTest3.TestMethod1");
- 18
- 19 Assert.AreEqual(user.Id, user2.Id);
- 20 }
- 21 }
看来没有什么问题。
来源: http://www.cnblogs.com/lanxiaoke/p/6502210.html