一. 温故而知新

  在开始学习Unity框架之前,有必要温习一下 【依赖倒置原则】和【手写IOC】, 因为我们框架代码的构建都是基于【依赖倒置原则】的,而Unity框架的核心思想就是IOC和DI,所以有必要了解通过【反射+工厂+配置文件】来实现手写IOC的原理。

  废不多说,简单提炼一下依赖原则的核心理念:面向接口编程。上层(UI层)不直接依赖于下层,而是依赖于下层对应的接口,下层去实现该接口。

  经典案例:业务层连接数据库,依赖接口,可以实现不改代码轻松切换数据库的目的。

  手动创建对象的三个阶段:直接new实例化→面向接口编程→将创建对象的交给工厂【手写IOC】。

 1         #region 手动创建对象几个阶段
 2             {
 3                 Console.WriteLine("--------------一.复习依赖倒置原则和手写IOC(简单工厂+反射+配置文件)----------------");
 4                 //1. 直接创建(需要添加对Service层的引用)
 5                 Console.WriteLine("--------------1. 直接创建----------------");
 6                 AndroidPhone androidPhone1 = new AndroidPhone();
 7                 androidPhone1.Call();
 8 
 9                 //2. 利用接口进行改造(需要添加对Service和Interface层的引用)
10                 Console.WriteLine("--------------2. 利用接口进行改造----------------");
11                 IPhone androidPhone2 = new AndroidPhone();
12                 androidPhone2.Call();
13 
14                 //3. 手写IOC(只需要添加Interface层的引用,但需要把Service层生成的DLL拷贝到该项目bin下)
15                 Console.WriteLine("--------------3. 利用接口进行改造----------------");
16                 IPhone androidPhone3 = ObjectFactory.CreateObject<IPhone>();
17                 androidPhone3.Call();
18 
19                 //总结:第三个阶段基本上已经是我们自己写容器的最高层次
20                 //下面我们将借助微软的第三方容器Unity来创建
21 
22             }
23             #endregion

依赖倒置原则详见:http://www.cnblogs.com/yaopengfei/p/7101347.html

手写IOC详见:http://www.cnblogs.com/yaopengfei/p/6891286.html

二. Unity深入浅出

 01-Unity深入浅出(一)

 (一). Unity介绍

 1. Unity的获取方式

   ①:下载网址:http://unity.codeplex.com/ 

      ②:通过Nuget获取  (目前最新版本为4.0.1)

01-Unity深入浅出(一)

2. Unity是什么?

   Unity是一个IOC容器,用它可以来创建对象,代替手写反射,它可以实现依赖注入(DI),它出自于微软。.Net平台下类似的其它IOC框架还有:Spring.Net、AutoFac、Castle等等。

3. IOC的含义

   IOC是一种目标,IOC的含义为控制反转,即原本上端(UI层)直接创建或使用的对象,交给第三方容器来装配和创建。

4.  DI的含义

     DI是一种手段,DI的含义为依赖注入,Unity提供三种方式分别是:属性注入、方法注入、构造函数注入。

 (二). 使用Unity来创建对象

 1. 创建对象的步骤

  ①:声明IUnityContainer容器。

  ②:通过RegisterType注册新类型 或者 通过RegisterInstance注册已经存在的类型。

  ③:通过Resove解析对象。

特别注意:注册类型时,可以指定名称来注册,用于同时创建注册多个类型时,Resove可以通过指定的注册名称来针对指定解析。

 2.  代码说明

   ①:代码结构(后面所有的代码说明都是基于这个结构的)

 详细说明:各个类的内容待写。

 01-Unity深入浅出(一)

 ②:直接创建简单对象(需要添加对Interface层和Service层的引用)

 1  {
 2                 Console.WriteLine("-------------------  二. Unity入门  -------------------");
 3                 Console.WriteLine("-------------------  01-直接创建对象  -------------------");
 4                 IUnityContainer container = new UnityContainer();
 5                 //进行注册,可以是:  接口-类、父类-子类、抽象类-子类。
 6                 //container.RegisterType<IPhone, AndroidPhone>();
 7                 //也可以用实例注册已经存在的对象
 8                 AndroidPhone android = new AndroidPhone();
 9                 container.RegisterInstance<IPhone>(android);
10                 //解析对象
11                 IPhone phone = container.Resolve<IPhone>();
12                 phone.Call();
13                 //我们会发现,虽然注册了AndroidPhone对象,但是该对象中的三个属性并没有实例化,依旧为空
14                 Console.WriteLine("phone.iHeadphone==null? {0}", phone.iHeadphone == null);
15                 Console.WriteLine("phone.iMicrophone==null? {0}", phone.iMicrophone == null);
16                 Console.WriteLine("phone.iPower==null? {0}", phone.iPower == null);
17  }

 详解:上述代码我们分别通过RegisterType注册类型、RegisterInstance注册已经存在的类型,我们会发现最终生成AndoridPhone中的三个属性并没有被实例化,那么怎么实例化里面的属性呢?这就涉及到后面的依赖注入了。

  ③. 指定命名来创建对象(需要添加对Interface层和Service层的引用)

 1    {
 2                 Console.WriteLine("-------------------  03-同时创建多个对象  -------------------");
 3                 //可以通过添加一个参数来区分
 4                 IUnityContainer container = new UnityContainer();
 5                 //注册类型时(指定命名)
 6                 container.RegisterType<IPhone, AndroidPhone>();
 7                 container.RegisterType<IPhone, ApplePhone>("apple");
 8                 container.RegisterType<IPhone, AndroidPhone>("android");
 9                 //依赖注入
10                 container.RegisterType<IMicrophone, Microphone>();
11                 container.RegisterType<IHeadphone, Headphone>();
12                 container.RegisterType<IPower, Power>();
13                 //解析对象
14                 IPhone iphone1 = container.Resolve<IPhone>();
15                 iphone1.Call();
16                 //解析对象(指定命名)
17                 IPhone iphone2 = container.Resolve<IPhone>("apple");
18                 iphone2.Call();
19                 IPhone iphone3 = container.Resolve<IPhone>("android");
20                 iphone3.Call();
21 
22                 //获取所有已注册且指定命名的对象(未指定命名的不能获取)
23                 var list = container.ResolveAll<IPhone>();
24 
25  }

  详解:注册类型时,如果默认不指定命名,则后面的会覆盖前面的,解析多个对象时,永远是最后一个注册的类型的对象。  所以RegisterType指定命名 、Resolve解析对象指定命名广泛用于同时创建多个对象的情况。

  我们发现上述代码有三句是依赖注入的,这个在下面讲解。

 (三). 依赖注入的三种形式

  Unity实现依赖注入有三种形式,分别是构造函数注入、属性注入、方法注入,分别对应三个特性:【InjectionConstructor】、【Dependency】、【InjectionMethod】,加上这三个特性表明构造函数中、属性中、方法中需要注入对象,使其实例化。

  方式一:属性注入。

  有WinPhone1类,实现了Iphone接口。其中WinPhone1类中的iMicrophone和iHeadphone两个属性上分别添加【Dependency】和【Dependency("fk")】,表明该属性对应的对象需要注入,其中iHeadphone需要Unity容器"指定命名"来注册类型。

1  public interface IPhone
2     {
3         void Call();
4         IMicrophone iMicrophone { get; set; }
5 
6         IHeadphone iHeadphone { get; set; }
7 
8         IPower iPower { get; set; }
9     }
View Code

相关文章:

  • 2022-01-19
  • 2022-01-05
  • 2021-08-06
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-15
  • 2022-12-23
猜你喜欢
  • 2021-08-19
  • 2021-09-14
  • 2021-08-29
  • 2021-11-18
  • 2021-12-28
  • 2021-06-14
  • 2021-11-15
相关资源
相似解决方案