博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOC详解和Unity基础使用介绍
阅读量:6074 次
发布时间:2019-06-20

本文共 3221 字,大约阅读时间需要 10 分钟。

说起IOC,可能很多初学者不知道是用来做什么的,今天正好有点时间,就来扫扫盲,顺便巩固下自己。

IOC全称是Inversion Of Control,意为控制反转(这些自然百度也有),可什么是控制反转呢?

按我现在的理解,把上端依赖的项从细节转换为抽象,并把细节转移到第三方,这个就叫控制反转。

怎么理解呢?最简单的:我们有一个接口I,就像这样:

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—— )。

说到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

你可能感兴趣的文章
STL - C++ 11的Lambda表达式(下)
查看>>
Redis学习系列二之.Net开发环境搭建及基础数据结构String字符串
查看>>
JS 总结
查看>>
面向切面编程(AOP)
查看>>
第三次作业
查看>>
JDBC编程:使用 Statement 修改数据库
查看>>
ES6学习笔记(二)
查看>>
http 请求类
查看>>
elasticsearch 服务安全配置
查看>>
R3.4.0安装包时报错“需要TRUE/FALSE值的地方不可以用缺少值”,需升级到R3.5.0
查看>>
Java学习3_一些基础3_16.5.7
查看>>
通过PowerShell获取域名whois信息
查看>>
Python基础之给函数增加元信息
查看>>
痞子衡嵌入式:开启NXP-MCUBootUtility工具的HAB加密功能 - CST(中英双语)
查看>>
洛谷——2639[USACO09OCT]Bessie的体重问题Bessie's We…——01
查看>>
(转)推荐系统—从入门到精通(论文选摘)
查看>>
HDOJ 1025 DP+二分
查看>>
maven的生命周期和插件
查看>>
研究 Table DOM对象的属性和方法
查看>>
android_orm框架之greenDAO(一)
查看>>