依赖注入(一)工厂

依赖注入(一)工厂

   许多时候我想等我把某些问题,完全想明白,完全理解透,再写点东西;事实往往相反,发现等我真正接近,把某些东西理解好,我自己再也不屑写点东西分享了,没有精神气也好,不着调也好,这对于我的性格至少是一个事实。懂得越多的人或理解的越深的时候,人越容易沉默;半调子的时候我一直在叫嚣,就像现在的我。

   决定改变方式,不要等想好了再动笔,也不要等完全弄明白了再动笔,看点写点。

小马过河,亲自走一走就会知道。

       “不要信我,否则你死得很惨!”

做事,不能只想。现在的我喜欢做,只需要想个清晰的目标就可以。

人想进步 就是不满足于现状,想把好东西投入生产就需要一点一滴的积累,做好技术的沉淀吧,这样面对高一点的层次时,也能游刃有余。

跑题了。下面开始举个栗子。在网上抄的,但很能说明问题。这里就让这段话来引入吧。

现实世界中,会有这么一种情况。

比如,汽车不会强依赖于某个品牌的轮胎,任何公司生产的轮胎,只要符合汽车的接口,就可以装在这个汽车上使用。

还有电脑的USB接口,只要符合USB标准的外设,就都能够接上电脑使用。

面向对象编程也是如此。

那到底什么是依赖注入呢?依赖注入(Dependency Injection)。简称DI,它还有另外一个名字,控制反转(Inversion of Control,英文缩写为IoC)。

   当某个角色(可能是一个实例,调用者)需要另一个角色(另一个实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在依赖注入里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由依赖注入容器来完成,然后注入调用者,因此也称为依赖注入。

用了些专业术语,有点高端大气上档次的感觉,我觉得其实就是抽象工厂,类似数据库抽象工厂DataAccess类(抽象工厂模式创建DAL)。

下面给出DataAccess类实现。需要配置web.config和加一个Cache包装类。

 1 public sealed class DataAccess<T>
 3 {
 5     private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["WebDAL"];
 7     /// <summary>
 9     /// 创建对象或从缓存获取
11     /// </summary>
13     public static object CreateObject(string path, string CacheKey)
15     {
17         object objType = DataCache.GetCache(CacheKey);//从缓存读取
19         if (objType == null)
       {
         try 25 { 27 objType = Assembly.Load(path).CreateInstance(CacheKey);//反射创建 29 DataCache.SetCache(CacheKey, objType);// 写入缓存 31 } 33 catch 35 { } 37 } 39 return objType; 41 } 42 43 /// <summary> 44 45 /// 根据配置文件生成一个传入的对象,并将其转为IDAL.IDAL泛型接口 46 47 /// </summary> 48 49 public static IDAL<T> GetIDAL(String Obj) 50 51 { 52 53 string CacheKey = path + "." + Obj; 54 55 object objType = CreateObject(path, CacheKey); 56 57 return (IDAL<T>)objType; 58 59 } 60 61 /// <summary> 62 63 /// 创建非IDAL接口的数据层接口 64 65 /// </summary> 66 67 public static T CreateDAL(String Obj) 68 69 { 70 71 string CacheKey = path + "." + Obj; 72 73 object objType = CreateObject(path, CacheKey); 74 75 return (T)objType; 76 77 } 78 79 }

上面又有点跑题的感觉。下面给出一个简单例子对比一下,体现出控制反转。

ChineseMan 有2个方法

 1 public class ChineseMan
 3 {
 5     public void Say()
 7     {
 9         Console.WriteLine("中文");
11     }
13     public void Sex()
15     {
17         Console.WriteLine("");
19     }
23  }

使用

 class Program
 {
     static void Main(string[] args)
     {
          ChineseMan cm =new ChineseMan();// 改变这里
          cm.Say(); 
          cm.Sex(); 
     } 
 }

当加入另一个人时就会出现

EnglishMan

 1 public class EnglishMan
 3 {
 5     public void Say()
 7     {
 9         Console.WriteLine("English");
11     }
13     public void Sex()
15     {
17         Console.WriteLine("male");
19     }
20  }
class Program
{
    static void Main(string[] args)
    {
        EnglishMan em=new EnglishMan();// 改变这里
        em.Say();
        em.Sex();
     }
}    

使用多态

//接口
public
interface IPeople { void Say(); void Sex(); }
//继承接口
public class ChineseMan : IPeople { public void Say() { Console.WriteLine("中文"); } public void Sex() { Console.WriteLine(""); } } public class EnglishMan : IPeople { public void Say() { Console.WriteLine("English"); } public void Sex() { Console.WriteLine("male"); } } static void Main(string[] args) {
   //多态 IPeople pe
= new ChineseMan(); pe.Say(); pe.Sex(); pe = new EnglishMan(); pe.Say(); pe.Sex(); }

使用工厂。

类还是上面多态中的。

工厂类

public class Factory
{
    public static IPeople GetPeople()
    {
        return new ChineseMan();//需要ChineseMan new ChineseMan()  需要EnglishMan new English()
    }
}
static void Main(string[] args)
{
    IPeople pe = Factory.GetPeople();
    pe.Say();
    pe.Sex();
 }

有人说,这不是还得在 Factory类中换需要new的具体类? 是的 但是在变化时Main方法却不需要重新编译,当有类似ChineseMan 类新加时只需要加类比如 ChineseWoman 类,只需加类并且 只改变Factory 类,Factory类做的再好点,就加反射。

public static IPeople GetPeople()
{
    object obj = Assembly.Load("IoCDemo").CreateInstance("IoCDemo.EnglishMan");//IoCDemo是namespace  namespace IoCDemo
    return obj as IPeople;//需要ChineseMan new ChineseMan()  需要EnglishMan new English()
}

IoCDemo IoCDemo.EnglishMan 这两个字符串可通过XML获得 在外部进行配置。这样就完全不需要改,只需要加类就行了。

下一篇介绍第三方依赖注入容器。

   解除依赖不仅让代码结构看起来更加合理,其带来的另一个好处是,各个部分可以单独的做单元测试,使得单元测试能够更加容易的进行。这个对于一些复杂度高的项目,对于保证项目的稳定性和可用性非常有意义。

原文地址:https://www.cnblogs.com/chengjunchao/p/3684038.html