一. 章前小节

 在前面的两个章节,我们运用依赖倒置原则,分别对 System.Web.Caching.Cache和 System.Runtime.Cacheing两类缓存进行了封装,并形成了ICache接口、RuntimeCacheHelp类和MemoryCacheHelp类。到这里,相当于万里长征已经走了一半,已经能面对基本的需求变更了。

在业务层中,如果我们需要使用RuntimeCacheHelp中封装的缓存类,我们可以这样用:

ICache iCache=new RuntimeCacheHelp()

iCache.方法名1  、  iCache.方法名2  、 iCache.方法名3 、iCache.方法名4 。

如果有一天,PM要求,改用MemoryCacheHelp类中的缓存,我们只需要将实例改为:

ICache iCache=new MemoryCacheHelp()。 其它使用iCache的位置统统不需要修改。

如果你仅仅满足于此,omg,那你的层次也太Low了,你是否想过?项目如果已经发布,我要切换缓存类型,难道我必须停止项目吗?是否有别的方式?(改配置文件?)你是否想过?一个用户每调用一次缓存相关的方法,都需要实例化一些 iCache对象?能否同一个用户保证实例唯一呢?能否所有用户保证实例唯一呢?

 以上的三个问题会在本章节和后续的几个章节陆续揭晓解决方案。

二. 工厂+反射+配置文件(IOC)进行多类型缓存的管理

1. 整体思路

  首先我们明确目的:我们要解决,项目发布以后,不需要停止项目,就可以切换缓存使用的类型。

  工厂:用来创建实例的地方。

  反射:不需要添加引用,动态加载程序集,可以获取程序集中的类中的方法,并进行调用。  反射详见:.Net进阶系列(2)-反射

  配置文件 : 可以将一些配置相关的信息写到app.config中,发布后可以,不需要停止项目,直接修正。

  工厂+反射+配置文件 这三者结合起来,其实就相当于IOC的原理。 IOC后面会结合Spring.Net 或 Unity进行详细介绍。

2. 详细步骤

 (1). 新建一个CacheFactory工厂类,工厂类里有一个静态的、返回值类型为ICache、名叫CreateCacheHelp的无参方法。该方法的目的就是用来创建ICache类型的实例。

   public class CacheFactory
{
public static ICache CreateCacheHelp()
{ } }

(2). 在配置文件中配置dll的名称和缓存类的名称

 <appSettings>
<add key="ICacheDllName" value="01-CacheUtils"/>
<!-- 格式: 命名空间.类名 -->
<add key="ICacheClassName" value="_01_CacheUtils.MemoryCacheHelp"/>
</appSettings>

(3). 在工厂中读取配置文件的信息,方便反射使用。

     public class CacheFactory
{
private static string ICacheDllName = ConfigurationManager.AppSettings["ICacheDllName"];
private static string ICacheClassName = ConfigurationManager.AppSettings["ICacheClassName"];
public static ICache CreateCacheHelp()
{
Console.WriteLine("--------------------------我要创建对象了----------------------------");
}
}

 (4). 利用反射加载程序集,并且通过Activator.CreateInstance(type)方法来创建对象。

 public class CacheFactory
{
private static string ICacheDllName = ConfigurationManager.AppSettings["ICacheDllName"];
private static string ICacheClassName = ConfigurationManager.AppSettings["ICacheClassName"];
public static ICache CreateCacheHelp()
{
Console.WriteLine("--------------------------我要创建对象了----------------------------");
Assembly assemble = Assembly.Load(ICacheDllName);
Type type = assemble.GetType(ICacheClassName);
//根据类型创建对象的方法
object obj = Activator.CreateInstance(type);
return (ICache)obj;
}
}

大功告成,可以尽情的使用了?  错,截止到这一步,我们仅仅是解决了项目发布后,不需要停止停止项目,通过修改配置文件就可以更改缓存的使用类型。

那么如果解决单线程内(单用户)内实例唯一问题呢,即创建了一次,下次不需要再创建,很多框架中都是采用CallContext数据槽来解决线程内实例唯一的问题(单线程)。即一次对话内CallContext中的数据共享,该次对话结束,CallContext中的数据也被销毁。

  public class CacheFactory
{
private static string ICacheDllName = ConfigurationManager.AppSettings["ICacheDllName"];
private static string ICacheClassName = ConfigurationManager.AppSettings["ICacheClassName"];
public static ICache CreateCacheHelp()
{
Console.WriteLine("--------------------------我要创建对象了----------------------------");
Assembly assemble = Assembly.Load(ICacheDllName);
Type type = assemble.GetType(ICacheClassName);
//根据类型创建对象的方法
object obj = Activator.CreateInstance(type);
return (ICache)obj;
} public static ICache CreateCacheHelp2()
{
ICache iCache = CallContext.GetData(typeof(CacheFactory).Name) as ICache;
if (iCache == null)
{
Console.WriteLine("--------------------------我要创建对象了----------------------------");
Assembly assemble = Assembly.Load(ICacheDllName);
Type type = assemble.GetType(ICacheClassName);
//根据类型创建对象的方法
iCache = (ICache)Activator.CreateInstance(type);
CallContext.SetData(typeof(CacheFactory).Name, iCache);
}
return iCache;
} }

. 简单的使用

在这里,简单的贴一段代码,说明一下使用,后续章节,会详细测试缓存的各种用法。

             {
//1.模拟场景:访问数据耗时操作,用到缓存(发现只有第一次耗时,其他从缓存中读取数据都是秒读)
Console.WriteLine("------------------ 1.模拟场景:访问数据耗时操作,用到缓存 ------------------------");
//ICache iCache = CacheFactory.CreateCacheHelp();
for (int i = ; i < ; i++)
{
ICache iCache = CacheFactory.CreateCacheHelp2();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
if (iCache.Contains("myData"))
{
var myData = iCache.Get<long>("myData");
Console.WriteLine("数据结果为:{0}", myData);
}
else
{
var myData = DBHelp.Query();
iCache.Add("myData", myData);
Console.WriteLine("数据结果为:{0}", myData);
}
stopwatch.Stop();
Console.WriteLine("第{0}次耗时为:{1}", i, stopwatch.ElapsedMilliseconds);
}
}

第三节:工厂+反射+配置文件(手写IOC)对缓存进行管理。的更多相关文章

  1. 闭关修炼180天--手写IOC和AOP(xml篇)

    闭关修炼180天--手写IOC和AOP(xml篇) 帝莘 首先先分享一波思维导图,涵盖了一些Spring的知识点,当然这里并不全面,后期我会持续更新知识点. 在手写实现IOC和AOP之前(也就是打造一 ...

  2. 手写IOC实现过程

    一.手写ioc前基础知识 1.什么是IOC(Inversion of Control 控制反转)? IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良 ...

  3. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...

  4. 手写IOC实践

    一.IOC 1.什么是IOC? 控制反转(英语:Inversion of Control,缩写为IoC),是[面向对象编程]中的一种设计原则,可以用来减低计算机代码之间的[耦合度]其中最常见的方式叫做 ...

  5. 初学源码之——银行案例手写IOC和AOP

    手写实现lOC和AOP 上一部分我们理解了loC和AOP思想,我们先不考虑Spring是如何实现这两个思想的,此处准备了一个『银行转账」的案例,请分析该案例在代码层次有什么问题?分析之后使用我们已有知 ...

  6. 手写IOC容器

    IOC(控制翻转)是程序设计的一种思想,其本质就是上端对象不能直接依赖于下端对象,要是依赖的话就要通过抽象来依赖.这是什么意思呢?意思就是上端对象如BLL层中,需要调用下端对象的DAL层时不能直接调用 ...

  7. 手写IOC框架

    1.IOC框架的设计思路 ① 哪些类需要我们的容器进行管理 ②完成对象的别名和对应实例的映射装配 ③完成运行期对象所需要的依赖对象的依赖

  8. 通过反射来手写简单的ORM SQlserver

    不说废话,直接上干货,如发现问题,欢迎大家指出,谢谢! //------------------------------------MySQlServerORM [简单 CURD] using Sys ...

  9. 我自横刀向天笑,手写Spring IOC容器,快来Look Look!

    目录 IOC分析 IOC是什么 IOC能够带来什么好处 IOC容器是做什么工作的 IOC容器是否是工厂模式的实例 IOC设计实现 设计IOC需要什么 定义接口 一:Bean工厂接口 二:Bean定义的 ...

随机推荐

  1. 转载 linux常用的监控命令工具

    工具 简单介绍top 查看进程活动状态以及一些系统状况vmstat 查看系统状态.硬件和系统信息等iostat 查看CPU 负载,硬盘状况sar 综合工具,查看系统状况mpstat 查看多处理器状况n ...

  2. [转帖]git命令参考手册

                      git init                                                  # 初始化本地git仓库(创建新仓库) git ...

  3. spring学习总结(一)_Ioc基础(下)

    本篇文章继续上篇文章讲解Ioc基础,这篇文章主要介绍零配置实现ioc,现在相信大家项目中也基本都是没有了xml配置文件.废话不多说.一起学习 代码示例 BookDao.java package com ...

  4. 51nod 1092(lcs)回文字符串

    题目:给你一个字符串,问添加最少的字符数目,使之成为回文串 解题思路:将字符串倒置,求出字符串和倒置串的最长公共子序列,字符串的长度减去lcs的长度就是了.. 代码:#include<iostr ...

  5. windows7下GithubDesktop和极域学生客户端冲突导致无法正常打开解决方案

    [出现问题] 很悲伤,今天GithubDesktop打开直接报错导致无法开启 报错如下 我的天呢,你敢相信连原因都不给我,但是这特么怎么可能难道我呢! 打开系统日志查看原因最终找到罪魁祸首!!! 计算 ...

  6. String类型的特殊之处

    String是一种特殊的引用类型,那么它究竟特殊在哪里? 请看看下面这个程序,输出什么结果? public static void changeStr(String str) { str = &quo ...

  7. 学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator

    前言 主要是完成微服务的监控,完成监控治理.可以查看微服务间的数据处理和调用,当它们之间出现了异常,就可以快速定位到出现问题的地方. springboot - version: 2.0 正文 依赖 m ...

  8. 51nod 1061 最复杂的数V2

    题目链接 51nod 1061 题面简述 求\([1, n]\)中约数个数最多的数. \(n \le 10^{200}\) 题解 首先,答案一定是一个反素数. 什么是反素数? 一个正整数\(x\)是反 ...

  9. 教程] 《开源框架-Afinal》之FinalHttp 01一步一脚

    1.FinalHttp是什么 :FinalHttp 对 HttpClient再次封装,最简洁的就是增加了许多回调的方法,对Get 和 Post 请求进行了简化.另外一点就是FinalHttp加入线程池 ...

  10. 服务器内存占用不断的增加 & 任务管理器(PF使用率)不断的增加:关注句柄数

    最近一二个月以来,我发现服务器的内存占用正按着每天60M的速度增加. 一台windows 2003的服务器(2G内存),刚刚启起时占用内存:600M左右. 运行20天后,内存占用(PF使用):1.8G ...