• 项目架构开发:数据访问层之Cache


    数据访问层简单介绍

    数据访问层,提供整个项目的数据访问与持久化功能。在分层系统中所有有关数据访问、检索、持久化的任务,最终都将在这一层完成。

    来看一个比较经典的数据访问层结构图

    大概可以看出如下信息

    1、有缓存、日志、异常处理、数据CRUD、查询及数据事务等功能

    2、无缝对接如EF、ADO.NET、NH、Dapper等数据访问技术

    3、对外只开放接口层,隐藏具体实现,这样就可以解耦业务层与数据访问层

    今天斗胆通过一个简单实例来实践一下,如有不妥的地方,欢迎指正

    创建接口层,定义可以提供的一些服务接口

    这里我们一个有5种服务接口,方法的功能就不介绍了,应该都能看懂

    缓存接口: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     }

    缓存服务的实现

    因为可能支持多种缓存,所以我实现了Web缓存与Redis缓存,这2中缓存分别在项目初期和后期集群中可能会用到

    我们来看HttpRuntimeCache.cs (还有一种Web缓存HttpContext.Cache,不够这种只能在Web应用使用,所以一般不推荐)

     1 public class HttpRuntimeCache<T> : ICache<T> 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<User>  cache = new HttpRuntimeCache<User>();
    2 var user = cache.Get("key");

    其实这样是不对的,因为这样的话接口ICache相当于没什么用处,没有起到应有的作用(隔离具体实现)

    如果要换另一种缓存实现(比如redis),那还要在所有使用了 new HttpRuntimeCache<User>() 的地方改正过来

    这样的耦合要去掉;有2种方式,通过IOC在实例化的时候依赖注入;另一种就是新建一个基础设施层,业务层依赖于这一层

    因为业务层肯定是需要调用一些Utilities、Helper等类型的工具类,这个应该是躲不掉的,再怎么接口隔离也去除不了这点

    基础设施层的实现

    Cache.cs 

     1     public sealed class Cache<T> where T : class
     2     {
     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 实现如下图

    至此,缓存功能实现完毕,我们新建一个测试项目看看结果

     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<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     }

    看来没有什么问题。

    项目架构开发系列

  • 相关阅读:
    MySQL基础
    mysql新
    第四章 常用模块
    第三章 函数编程
    第二章 数据类型和文件操作
    基础语法
    day24 面向对象与实例属性
    day21
    详解 Eclipse 中的快速 Java 编码(代码模板)
    补缴2个月社保折腾1年多 刁钻政策玩死人
  • 原文地址:https://www.cnblogs.com/lanxiaoke/p/6502210.html
Copyright © 2020-2023  润新知