加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 05:42:41 所属栏目:百科 来源:网络整理
导读:解构控制反转(IoC)和依赖注入(DI) 1.控制反转 控制反转(Inversion ofControl,IoC),简言之就是代码的控制器交由系统控制,而不是在代码内部,通过IoC,消除组件或者模块间的直接依赖,使得软件系统的开发更具柔性和扩展性。控制反转的典型应用体现在

解构控制反转(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://www.voidcn.com/article/p-mtfsjtot-ot.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读