解构控制反转(IoC)和依赖注入(DI)

1.控制反转

控制反转(Inversion ofControl,IoC),简言之就是代码的控制器交由系统控制,而不是在代码内部,通过IoC,消除组件或者模块间的直接依赖,使得软件系统的开发更具柔性和扩展性。控制反转的典型应用体现在框架系统的设计上,是框架系统的基本特征,不管是.NET Framework抑或是Java Framework都是建立在控制反转的思想基础之上。

控制反转很多时候被看做是依赖倒置原则的一个同义词,其概念产生的背景大概来源于框架系统的设计,例如.NET Framework就是一个庞大的框架(Framework)系统。在.NET Framework大平台上可以很容易地构建ASP.NET Web应用、Silverlight应用、Windows Phone应用或者WindowAzure Cloud应用。很多时候,基于.NET Framework构建自定义系统的方式就是对.NET Framework本身的扩展,调用框架提供的基础API,扩展自定义的系统功能和行为。然而,不管如何新建或者扩展自定义功能,代码执行的最终控制权还是回到框架中执行,再交回应用程序。黄忠诚先生曾经在ObjectBuilder Application Block一文中给出一个较为贴切的举例,就是在Window From应用程序中,当Application.Run调用之后,程序的控制权交由WindowsFroms Framework上。所以,控制反转更强调控制权的反转,体现了控制流程的依赖倒置,所以从这个意义上来说,控制反转是依赖倒置的特例。

2.依赖注入

依赖注入(DependencyInjection,DI),早见于Martin Flower的Inversion of ControlContainers and the Dependency Injection pattern一文,其定义可概括为:

客户类依赖于服务类的抽象接口,并在运行时根据上下文环境,由其他组件(例如DI容器)实例化具体的服务类实例,将其注入到客户类的运行时环境,实现客户类与服务类实例之间松散 的耦合关系。

(1)常见的三种注入方式

简单而言,依赖注入的方式被总结为以下三种。

·  接口注入(Interface Injection),将对象间的关系转移到一个接口,以接口注入控制。

首先定义注入的接口:

public interface IRunnerProvider

{

void Run(Action action);

}

为注入的接口实现不同环境下的注入提供器,本例的系统是一个后台处理程序提供了运行环境的多种可能,默认情况下将运行于单独的线程,或者通过独立的Windows Service进程运行,那么需要为不同的情况实现不同的提供器,例如:

public class DefaultRunnerProvider : IRunnerProvider

{

#region IRunnerProvider Members

public void Run(Action action)

{

var thread = new Thread(() => action());

thread.Start();

}

#endregion

}

对于后台服务的Host类,通过配置获取注入的接口实例,而Run方法的执行过程则被注入了接口所定义的逻辑,该逻辑由上下文配置所定义:

public class RunnerHost : IDisposable

{

IRunnerProvider provider = null;

public RunnerHost()

{

// GetProvider by configuration

provider = GetProvider(config.Host.Provider.Name);

}

public void Run()

{

if (provider != null)

{

provider.Run(() =>

{

// exceute logic in thisprovider, if provider is DefualtRunnerProvider,

// then this logic will run in a new thread context.

});

}

}

}

接口注入,为无须重新编译即可修改注入逻辑提供了可能,GetProvider方法完全可以通过读取配置文件的config.Host.Provider.Name内容,来动态地创建对应的Provider,从而动态地改变BackgroundHost的Run()行为。

·  构造器注入(Constructor Injection),客户类在类型构造时,将服务类实例以构造函数参数的形式传递给客户端,因此服务类实例一旦注入将不可修改。

public class PicWorker

{

}

public class PicClient

{

private PicWorker worker;

public PicClient(PicWorker worker)

{

// 通过构造器注入

this.worker = worker;

}

}

·  属性注入(Setter Injection),通过客户类属性设置的方式,将服务器类实例在运行时设定为客户类属性,相较构造器注入方式,属性注入提供了改写服务器类实例的可能。

public class PicClient

{

private PicWorker worker;

// 通过属性注入

public PicWorker Woker

{

get { return this.worker; }

set { this.worker = value; }

}

}

另外,在.NET平台下,除了Martin Flower大师提出的三种注入方式之外,还有一种更优雅的选择,那就是依靠.NET特有的Attribute实现,以ASP .NET MVC中的ActionFilter为例:

[HttpPost]

public ActionResult Register(RegisterModel model)

{

// 省略注册过程

return View(model);

}

其中,HttpPostAttribute就是通过Attribute方式为RegisterAction注入了自动检查Post请求的逻辑,同样的注入方式广泛存在于ASP .NET MVC的很多Filter逻辑中。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

public sealed class HttpPostAttribute : ActionMethodSelectorAttribute

{

// Fields

private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);

// Methods

public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)

{

return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);

}

}

关于Attribute的详细内容,请参考8.3节“历史纠葛:特性和属性”,其中的TrimAttribute特性正是应用Attribute注入进行属性Trim过滤处理的典型应用。

本文节选自《你必须知道的.NET(第2版)》一书

图书详细信息:http://blog.csdn.net/broadview2006/article/details/6673353

解构控制反转(IoC)和依赖注入(DI)相关推荐

  1. java-12:spring MVC - 控制反转IOC,依赖注入DI

    学习spring框架之前,先理解几个概念: 1.第一部分:依赖倒置原则 2.第二部分:控制反转,控制反转容器(实例) 3.第三部分:控制反转,控制反转容器(全面理解,面试题) 综合性理解:控制反转(I ...

  2. 控制反转(IoC)与依赖注入(DI)详解

    文章目录 什么是控制反转(IoC) 控制反转(IoC)有什么作用 控制反转(IoC)是怎么分类的 依赖注入 接口注入 Setter方法注入 构造器注入 依赖查找 上下文依赖查找(Contextuali ...

  3. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 "Inversion of Control".依赖注入DI, 全称 "Dependency Injection". 面向的问题:软件开发 ...

  4. 依赖倒置(DIP),控制反转(IoC)与依赖注入(DI)

    DIP,IoC与DI概念解析 依赖倒置 DIP(Dependency Inversion Principle) DIP的两大原则: 1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象. 2.抽象不 ...

  5. 控制反转IOC与依赖注入DI

    为什么80%的码农都做不了架构师?>>>    1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最 ...

  6. 控制反转IOC、依赖注入DI的详细说明与举例

    文章目录 引入 IOC介绍 IOC的实现 通过构造函数注入依赖 通过 setter 设值方法注入依赖 依赖注入容器 IOC优缺点 优点 缺点 阅读时忽略语言差异,参考了很多其他博主内容,参考博文在最后 ...

  7. Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)

    目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 ...

  8. 控制反转 IOC 与依赖注入 DI

    引言 简单总结和巩固一下spring的核心原理--IOC和DI的概念,为什么IOC要叫控制反转?IOC和DI的关系是怎样的? 一.IOC 控制反转 初学者可能很好奇,为什么spring framewo ...

  9. [教程]控制反转(IoC)与依赖注入(DI)

    来源: http://zhangjunhd.blog.51cto.com/113473/126530/ 挺简单的,说的也很清楚 ※IoC/DI 依赖Java的反射机制 1.控制反转(Inversion ...

  10. (转载)控制反转(IoC)与依赖注入(DI)

    http://zhangjunhd.blog.51cto.com/113473/126530/ 转载于:https://www.cnblogs.com/eecs2016/articles/741709 ...

最新文章

  1. seaborn系列 (14) | 条形图barplot()
  2. 以一致的体验交付和管理云原生多集群应用
  3. super与this关键字的区别
  4. 5-2利用MapReduce进行数据排序
  5. cmd 根据计算机名查ip地址_如何查找和更改Mac上的IP地址
  6. java私塾架构二,小弟我在Java私塾学习期间的学习源码
  7. 小白软件帮手(xbrjbs)一个专业安装破解软件的公众号
  8. 报数游戏c语言,报数游戏-实战简单设计
  9. 【基于ARM cortex-A53的音视频】
  10. VHDL移位操作的两种方式,及乘除运算中小数倍的解法
  11. 英文原文:6 Life Habits That Programming Could Teach You Today
  12. 《低代码指南100解决方案》——5疫情防控常态化之下,如何做好访客管理?
  13. 人工蜂群算法(Artificial Bee Colony, ABC)MATALAB代码详细解析
  14. maven lastUpdated 文件清理脚本
  15. np.random.normal()的含义及实例
  16. idea 离线安装translation 谷歌翻译
  17. 对抗恶意软件,反病毒软件还有戏吗?
  18. 转载--徐小平:不做人生规划,你离挨饿只有三天
  19. 计算机毕业论文人事管理系统,计算机人事管理系统毕业论文设计.doc
  20. python实现对数转换_对数变换(一些基本的灰度变换函数)基本原理及Python实现...

热门文章

  1. 【排列组合】ZSC1076: 数学、不容易系列之三——考新郎
  2. Qt5.3.2(VS2010)_调试_进入Qt源码
  3. hdu 4288 线段树 暴力 **
  4. absolute绝对定位的参考坐标和参考对象问题详解
  5. 对权值线段树剪枝的误解--以HDU6703为例
  6. Openfire Meetings插件是一个包含各种Jitsi项目(如VideoBridge和Meet)的实现
  7. python HTTP请求过程
  8. 《学习笔记》Maven
  9. GET POST 传值与接收案例
  10. 如何获取ezui tree 所有子节点