IOC详解和Unity基础使用介绍
说起IOC,可能很多初学者不知道是用来做什么的,今天正好有点时间,就来扫扫盲,顺便巩固下自己。
IOC全称是Inversion Of Control,意为控制反转(这些自然百度也有),可什么是控制反转呢?
按我现在的理解,把上端依赖的项从细节转换为抽象,并把细节转移到第三方,这个就叫控制反转。
怎么理解呢?最简单的:我们有一个接口Ianimal,就像这样:
|
1
2
3
4
|
public interface iAnimal { void talk(); } |
然后我们现在用另一个类去实现该接口:
|
1
2
3
4
5
6
7
|
public class dog : iAnimal { public void talk() { Console.Write("小狗说:汪汪汪!"); } } |
然后呢,往常来讲,我们应该是这样调用的:
|
1
2
3
|
iAnimal dog = new dog();dog.talk();Console.ReadKey(); |
运行结果应该是这样的:

到目前为止都是正确的,相信各位小伙伴一般也是如此。
但请注意,我们在调用时是直接用dog类型new出来的,这种做法其实就已经依赖于细节了。
那么如何将这里依赖的细节修改为抽象呢?很简单,我们只需要一个工厂类帮助我们生成实际的类即可。
但是有些小伙伴可能想,工厂内也有细节啊,难道写个工厂就是IOC了么?
当然不是,我们还将细节交给配置文件(通过反射),这样在功能变动时,无需修改原代码,只需要修改配置文件即可。
工厂看上去是这样的:
|
1
2
3
4
5
6
7
8
9
10
|
public class SimpleFactory { public static iAnimal CreateAnimal() { string classModule = ConfigurationManager.AppSettings["PhoneType"]; Assembly assembly = Assembly.Load(classModule.Split(',')[1]); Type type = assembly.GetType(classModule.Split(',')[0]); return (iAnimal)Activator.CreateInstance(type); } } |
而我们的配置文件自然也要写点东西了:
|
1
2
3
|
<appSettings> <add key="AnimalType" value="IOCandDI.dog,IOCandDI"/></appSettings> |
value内,逗号前是类的全限定名(命名空间+类名),后面是命名空间。
不会操作配置文件的小伙伴们,先添加这个引用:

然后引入System.Configuration命名空间就可以操作啦。
至于反射,直接引入System.Reflection 命名空间即可操作。反射的原理也很简单,在这里就不再赘述。
修改过后的调用和以前的调用对比:
|
1
2
3
4
5
6
|
iAnimal dog = new dog();dog.talk();iAnimal obj = SimpleFactory.CreateAnimal();obj.talk();Console.ReadKey(); |
结果是一样的:

这个时候,如果再多一种动物,只需要添加一个继承iAnimal接口的类,并且修改配置文件即可。
IOC带给我们的便利正是如此。
微软也推出了一款IOC的插件,叫做Unity,你在NuGet程序包管理中很轻松就能找到它:

首先是下载与安装:

然后在页面引入Microsoft.Practices.Unity就可以操作了,基本流程如下:
|
1
2
3
4
|
IUnityContainer container = new UnityContainer();//声明容器container.RegisterType<iAnimal, cat>();//注册类型iAnimal obj = container.Resolve<cat>();//完成实例obj.talk(); |
运行效果:

了解了Unity的基础用法,我们在来看下如何利用Unity做依赖注入(DI——dependency injection)。
说到DI,就一定要知道DI的三种方式:属性注入、构造注入、方法注入。我这里直接改造了cat类:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class cat : iAnimal { [Dependency] public iColor color { get; set; } public iEat eat { get; set; } public iRun run { get; set; } [InjectionConstructor] public cat(iEat ieat) { eat = ieat; } public void talk() { Console.WriteLine("小猫说:喵喵喵!"); } [InjectionMethod] public void Happy(iRun irun) { run = irun; } } |
大家一定发现了我分别在属性、构造、方法头上加了特性。
实际上,Dependency、InjectionConstructor、InjectionMethod就是Unity中DI操作的标识符,它们分别对应属性注入、构造注入、方法注入。
那么,这些特性是如何帮助程序完成DI的呢?看调用代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
IUnityContainer container = new UnityContainer();container.RegisterType<iAnimal, cat>();container.RegisterType<iColor, Color>();container.RegisterType<iEat, Eat>();container.RegisterType<iRun, Run>();iAnimal obj = container.Resolve<cat>();obj.talk();cat myCat = (cat)obj;Console.WriteLine("myCat.color是空的么?{0}", myCat.color == null);Console.WriteLine("myCat.eat是空的么?{0}", myCat.eat == null);Console.WriteLine("myCat.run是空的么?{0}", myCat.run == null);Console.ReadKey(); |
在Unity容器内类型注册时,需注册cat类内3个参数的类型,用来对应3种注入方式。
运行结果如下:

3种注入方式都成功了~添加了特性的属性(或方法)在Unity容器执行实例时会自动寻找上面3个特性(的位置)并匹配注册类型(完成注入)。
需要注意的是,构造注入无需声明特性也可生效,Unity会自动寻找参数最多的构造参数进行注入(前提是被注入的参数类型一定要注册)。
ADD:在和一位小伙伴讨论时,他指出了我unity的使用方法有问题,我这里的确没有将unity容器的细节抽出到配置文件中(因为想着是基础使用教程就没有加),这一方面我也懒得再写,找到一篇介绍详细的博文供大家参考——http://www.cnblogs.com/junchu25/archive/2012/08/10/2631455.html
IOC详解和Unity基础使用介绍的更多相关文章
- NET笔记——IOC详解和Unity基础使用介绍
说起IOC,可能很多初学者不知道是用来做什么的,今天正好有点时间,就来扫扫盲,顺便巩固下自己. IOC全称是Inversion Of Control,意为控制反转(这些自然百度也有),可什么是控制反转 ...
- Spring4 IOC详解
Spring4 IOC详解 上一章对Spring做一个快速入门的教程,其中只是简单的提到了IOC的特性.本章便对Spring的IOC进行一个详解.主要从三个方面开始:基于xml文件的Bean配置,基于 ...
- IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)
IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...
- JAVASCRIPT事件详解-------原生事件基础....
javaScirpt事件详解-原生事件基础(一) 事件 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能 ...
- 淘宝JAVA中间件Diamond详解(2)-原理介绍
淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...
- 开源项目MultiChoiceAdapter详解(一)——概要介绍
项目地址:https://github.com/ManuelPeinado/MultiChoiceAdapter 这个项目主要是提供了一个多选适配器,使用者可以用它来替换传统的适配器,用途还算比较广泛 ...
- IIS负载均衡-Application Request Route详解第一篇: ARR介绍
IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...
- Spring IoC详解
Spring IoC详解 1. 控制反转 控制反转是一种通过描述(XML或者注解)并通过第三方去产生或获取特定对象的方式.在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Depend ...
- 【Vue】详解组件的基础与高级用法
Vue.js 最核心的功能就是组件(Component),从组件的构建.注册到组件间通信,Vue 2.x 提供了更多方式,让我们更灵活地使用组件来实现不同需求. 一.构建组件 1.1 组件基础 一个组 ...
随机推荐
- T-sql语句修改数据库逻辑名、数据库名、物理名(sql2000)
--更改MSSQL数据库物理文件名Sql语句的写法 --注意:要在活动监视器里面确保没有进程连接你要改名的数据库!!!!!!!!!!!!!!!!!!!! -- Sql语句如下 USE master - ...
- js和php计算图片自适应宽高算法实现
js Code: <script> $width = $(imgobj).width(); //图原始宽 $newheight = $(imgobj).height(); //图原始高 $ ...
- C++中memcpy和memmove
二者都是内存拷贝 memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝.那么既然memcpy和memmove二者 ...
- MongoDB图形化管理工具Toad Mac Edition
昨天介绍了在Mac上安装MongoDB,安装好并配置环境变量后,在终端上用mongo命令就可以进入MongoDB的命令行管理界面,但我更习惯在图形化界面下管理数据库,这样更直观.今天我再介绍一款在Ma ...
- redis在Linux下的远程连接
1.redis在Linux下的远程连接: $ redis-cli -h host -p port -a password 如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass ...
- 洛谷P3605 [USACO17JAN] Promotion Counting 晋升者计数 [线段树合并]
题目传送门 Promotion Counting 题目描述 The cows have once again tried to form a startup company, failing to r ...
- react篇章-事件处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- 虚拟机hadoop集群搭建
hadoop tar -xvf hadoop-2.7.3.tar.gz mv hadoop-2.7.3 hadoop 在hadoop根目录创建目录 hadoop/hdfs hadoop/hdfs/tm ...
- rabbitmq学习(二) —— helloword!
rabbitmq学习当然是跟着官网走最好了,官网的教程写的很好,跟着官网教程走一遍就会有个初步了解了 下面的教程转自http://cmsblogs.com/?p=2768,该博客对官网的翻译还不错 介 ...
- JAVAEE——SSH项目实战04:联系人添加、列表显示和修改
作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7159337.html 一.联系人添加 1.添加页面设计 linkman/list. ...