测试代码链接
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。IoC可以认为是一种全新的设计模式

在面向对象编程中对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。伴随应用规模越来越庞大,对象之间的依赖关系也越来越复杂,对象之间耦合度越来越高。对于应用功能的修改和扩展必然会出现牵一发而动全身的情形。

耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson 1996年提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中。

IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。

由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

IoC模式,系统中通过引入实现了IoC模式的IoC容器,即可由IoC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分离。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。

IoC是一个很大的概念,可以用不同的方式实现。其主要形式有两种:
依赖查找:容器提供回调接口和上下文条件给组件。EJB和Apache Avalon 都使用这种方式。这样一来,组件就必须使用容器提供的API来查找资源和协作对象,仅有的控制反转只体现在那些回调方法上,容器将调用这些回调方法,从而让应用代码获得相关资源。

依赖注入:组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)

优缺点:
IoC最大的好处是什么?因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拔(有点像USB接口和SCSI硬盘了)。
IoC最大的缺点是什么?(1)生成一个对象的步骤变复杂了(事实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。(2)对象生成因为是使用反射编程,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。(3)缺少IDE重构操作的支持,如果在Eclipse要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有XML方式的缺憾所在。


分层架构是软件开发基本的要求,上图简单展示了ioc这种设计手段在分层架构中的扮演的角色(一个对象的容器,对象工厂)。
DIP依赖倒置原则:系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖,依赖抽象,而不是细节
贯彻依赖倒置原则,左边能抽象,右边实例化的时候不能直接用抽象,所以需要借助一个第三方

高层本来是依赖低层,但是可以通过工厂(容器)来决定细节,去掉了对低层的依赖
IOC控制反转:把高层对低层的依赖,转移到第三方决定,避免高层对低层的直接依赖(是一种目的)那么程序架构就具备良好扩展性和稳定性
DI依赖注入:是用来实现IOC的一种手段,在构造对象时,可以自动的去初始化,构造函数注入,属性注入,方法注入,不管是构造对象,还是注入对象,这里都是靠反射做到的,有了依赖注入,才可能做到无限层级的依赖抽象,才能做到控制反转。

通过以上文字简单了解了什么是IOC,下面将使用unity实现简单的ioc案例

NuGet包管理器安装Unity version=“5.8.6”

IOC工厂类

using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Resolution;namespace IOC.Factory
{public class UnityIocHelper{#region 构造方法/// <summary>/// 构造方法/// </summary>/// <param name="containerName">容器名称</param>private UnityIocHelper(string containerName){UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");if (containerName == "IOCcontainer"){_container = new UnityContainer();section.Configure(_container, containerName);}else if (section.Containers.Count > 1){_container = new UnityContainer();section.Configure(_container, containerName);}}#endregion#region 属性/// <summary>/// 容器/// </summary>private readonly IUnityContainer _container;/// <summary>/// 容器实例/// </summary>private static readonly UnityIocHelper instance = new UnityIocHelper("IOCcontainer");/// <summary>/// UnityIoc容器实例/// </summary>public static UnityIocHelper Instance{get { return instance; }}#endregion#region 获取对应接口的具体实现类/// <summary>/// 获取实现类(默认映射)/// </summary>/// <typeparam name="T">接口类型</typeparam>/// <returns>接口</returns>public T GetService<T>(){return _container.Resolve<T>();}/// <summary>/// 获取实现类(默认映射)带参数的/// </summary>/// <typeparam name="T">接口类型</typeparam>/// <param name="parameter">参数</param>/// <returns>接口</returns>public T GetService<T>(params ParameterOverride[] parameter){return _container.Resolve<T>(parameter);}/// <summary>/// 获取实现类(指定映射)带参数的/// </summary>/// <typeparam name="T"></typeparam>/// <param name="name"></param>/// <param name="parameter"></param>/// <returns>接口</returns>public T GetService<T>(string name, params ParameterOverride[] parameter){return _container.Resolve<T>(name, parameter);}#endregion#region 判断接口是否被注册了/// <summary>/// 判断接口是否被实现了/// </summary>/// <typeparam name="T">接口类型</typeparam>/// <returns>bool</returns>public bool IsResolve<T>(){return _container.IsRegistered<T>();}/// <summary>/// 判断接口是否被实现了/// </summary>/// <typeparam name="T">接口类型</typeparam>/// <param name="name">映射名称</param>/// <returns></returns>public bool IsResolve<T>(string name){return _container.IsRegistered<T>(name);}#endregion}
}

接口层

业务层

对象的依赖注入只需要标识对应的特性,并在配置文件中添加对应对象的配置,就能实现相互依赖对象的自动构造。

将要用ioc容器构造的对象由配置文件配置

使用对象时将不用显示初始化

利用ioc工厂配置,对于拥有共同接口的业务扩展,只需要修改配置文件并添加扩展业务的dll文件即可直接使用,不用修改原始代码。


通过AOP对扩展对象IOC.ServiceExt.Phonex增加异常和日志处理

Unity实现IOC容器相关推荐

  1. [IoC容器Unity]第四回:使用范例

    1.引言 前面几个章节介绍了Unity的基本使用,主要分为程序和配置文件两种方法的使用,可以参考一下链接, [IoC容器Unity]第一回:Unity预览 [IoC容器Unity]第二回:Lifeti ...

  2. 深入理解DIP、IoC、DI以及IoC容器

    对于大部分小菜来说,当听到大牛们高谈DIP.IoC.DI以及IoC容器等名词时,有没有瞬间石化的感觉?其实,这些"高大上"的名词,理解起来也并不是那么的难,关键在于入门.只要我们入 ...

  3. 企业级应用框架(五)IOC容器在框架中的应用

    前言 在上一篇我大致的介绍了这个系列所涉及到的知识点,在本篇我打算把IOC这一块单独提取出来讲,因为IOC容器在解除框架层与层之间的耦合有着不可磨灭的作用.当然在本系列前面的三篇中我也提供了一种基于反 ...

  4. Ioc容器Autofac介绍

    Autofac是轻量级的开源Ioc容器,在这里可以下载http://code.google.com/p/autofac/.如果你用过其他的Ioc容器,那么学习Autofac使用也会比较容易,下面将通过 ...

  5. 依赖反转原理,IoC容器和依赖注入:第5部分

    目录 介绍 总览 依赖注册 实例注册 工厂注册 类型注册 样例应用程序 总结 介绍 这是我关于依赖反转原理和依赖注入的文章的第五部分也是最后一部分.在上一部分中,我实现了一个自定义容器,其功能非常有限 ...

  6. 依赖反转原理,IoC容器和依赖注入:第4部分

    目录 介绍 背景 LifeTimeOption的实现 总结 下载源代码18.5 KB 介绍 这是我有关依赖反转原理,IoC容器和依赖注入的文章的第四部分.在本文的上半部分,我试图解释如何构建自己的Io ...

  7. 依赖反转原理,IoC容器和依赖注入:第3部分

    目录 介绍 背景 自定义IoC容器的工作方式 自定义IoC容器 高级模块的使用者 编码自定义IoC容器 步骤1:在Visual Studio中创建一个空白解决方案,并创建以下项目 步骤2:将以下代码添 ...

  8. 依赖反转原理,IoC容器和依赖注入:第2部分

    目录 介绍 控制反转(IoC) 什么是控制反转 接口反转 流反转 创建反转 依赖注入 总结 介绍 这是有关依赖反转原理,IoC容器和依赖注入的文章的继续部分.在本文的上半部分,我解释了什么是依赖反转原 ...

  9. 依赖反转原理,IoC容器和依赖注入:第1部分

    目录 介绍 先决条件 依赖倒置原则(DIP) 总结 介绍 在处理WPF应用程序时,我遇到过诸如Unity容器,IoC,依赖注入之类的术语.当时,我很迷茫,想着这一切的需要.但后来,当我逐渐了解到它的好 ...

最新文章

  1. Java类的加载过程详解 面试高频!!!值得收藏!!!
  2. 使用加密工具类进行有效的字符串加密——CSDN博客
  3. 台式计算机欢迎界面下不去,Win7系统开机不显示欢迎界面的方法
  4. 32位单精度浮点乘法器的FPGA实现
  5. IDEA配置tomcat部署web项目时没有artifacts
  6. 微软全球执行副总裁沈向洋离职;马云回应双十一数据作假;GitHub 官方终于出 App 了! | 极客头条...
  7. CF813E Army Creation
  8. [Hadoop]SSH免密码登录以及失败解决方案
  9. [摘译]js内存泄漏常见的四种情况
  10. macos安装vscode_什么!你还没有安装Flutter!
  11. ZOJ 3492 模拟循环链表线性查找
  12. druid Approximate Histograms
  13. 9月第1周文学类网站/频道:新浪文学超起点居首
  14. 灰狼优化算法与影响力最大化问题
  15. php mysql多条件查询界面_PHP组合查询多条件查询实例代码
  16. 【转】SQL修改字段长度
  17. 人人都该了解的思维修炼
  18. 132,怎样理解帝国和王朝的兴衰
  19. 剪切caspase3_Caspase-3活性检测
  20. [转]90后准程序员写给前辈们的一封…

热门文章

  1. 这样用信用卡就好了?其实你这是被坑了
  2. android h5 唤起app,h5唤起app解决方案
  3. 实时操作系统的滴答Tick设置多少才合适?
  4. python绘制渐变图_Python利用imshow制作自定义渐变填充柱状图(colorbar)
  5. word2vec中单词向词向量的转换过程详解
  6. 论述计算机在现代社会中的地位与作用,媒介在现代社会有什么地位和意义
  7. FFT频谱分析(补零、频谱泄露、栅栏效应、加窗、细化、频谱混叠、插值),Matlab、C语言代码
  8. 图神经网络入门 (GNN, GCN)
  9. 面向计算思维培养的PBL教学模式设计以模式识别课程为例
  10. 华为设备中QinQ的应用