IoC

转载 2006年05月17日 01:29:00

最近IoC很热门,一般翻译为控制反转,也就是一个类将一些工作交给framework(或者控制器)来做。从本质上讲是面向对象的设计原则之一——接口可具体实现的分离的一个具体体现,对象之间解耦的一种方法。

比如说,我们希望设计一个更好用的DropDownList控件,它可以按照如下的方式工作

在这里,我们只关注DataSourceKey这个属性,DataSourceKey是指控件希望根据这个key就可以得到data source,然后自动绑定,那么怎么根据key来得到data source呢,我们需要一个services来完成这件工作

于是我们定义一个接口 IDataSourceProvider

interface IDataSourceProvider
{ ICollection GetDataSource(string key); }

然后有一个类来实现这个接口
class MyDataSourceProvider : IDataSourceProvider
{
ICollection GetDataSource(string key)
{ ... }
}

class ExDropDownList
{
IDataSourceProvider myProvider;

......

if(AutoBind==true &&
IsDataBound
==false)
{
IDataSourceProvider myProvider= (IDataSourceProvider) new MyDataSourceProvider ();
DataSource = myProvider.GetDataSource(DataSourceKey);
DataBind();
}

..............
}


这不是一种好的做法,因为这种实现方法大大加强了ExDropDownList和DataSourceProvider之间的依赖关系,在这个例子里,ExDropDownList不仅依赖接口IDataSourceProvider,而且依赖接口的具体实现MyDataSourceProvider,不符合面向对象的原则,如果只是自己项目用问题还不是很大,但是如果别的team也希望用这个控件,但是他们有另外一种提供data source的方法,那么应该怎么办呢。

解耦的办法由很多种,其中一种是把具体创建IDataSourceProvider实例的工作交给容器或者framework来做,也就是说将对IDataSourceProvider的控制反转,有容器决定创建哪一个IDataSourceProvider实例,

接下来,怎么把创建好的IDataSourceProvider实例告诉ExDropDownList呢(或者说注入,Injection)
有三种方法,一种是构造注入,也就是在创建ExDropDownList时就告诉它,哪一个IDataSourceProvider实例可以为你提供GetDataSource的服务

class ExDropDownList
{
private IDataSourceProvider provider;

ExDropDownList(IDataSourceProvider provider)
{
this.Provider = provider;
}
}


另一种方法是设值注入,也就是ExDropDownList对外公布一个方法setProvider或者公布一个属性Provider,让容器可以把创建好的IDataSourceProvider实例传给ExDropDownList。

class ExDropDownList
{
private IDataSourceProvider provider;

public Provider
{
get{}
set{}
}
}

....
ExDropDownList.Provider = (IDataSourceProvider) new MyDataSourceProvider ()
....

第三种是接口注入,也就是说调用者和服务提供者定义一个协议,ExDropDownList如果需要使用DataSourceProvider提供的服务,就需要根据协议实现一个InjectProvider的接口,以便于容器通过这个接口将IDataSourceProvider实例传给ExDropDownList

interface IInjectProvider
{ viod SetProvider(IDataSourceProvider provider ); }

class ExDropDownList : IInjectProvider
{
SetProvider(IDataSourceProvider provider)
{
this.provider = provider;
}
}


((IInjectProvider)ExDropDownList).SetProvider(IDataSourceProvider) new MyDataSourceProvider ());

接口注入的方法因为对象间还是有很高的耦合度,所以应用不是很广泛。

构造注入和设值注入那一种更好呢。
martin fowler给出了一个解释:
构造注入和设值注入反映了面向对象编程的一个普遍问题,应该在哪里填充对象的字段,是在创建对象时还是通过属性或者方法来设定值。martin fowler建议在对象构造时就创建完正合法的对象,这样做还有一个好处就是可以隐藏不可改变的字段(注:或者不应该在运行期间随意
改变的字段),而公布一个设置方法,就意味着调用者可以自由改变字段的值。

凡事总有例外,如果参数太多,构造注入使系统显得有点凌乱,而且有些时候没有办法使用构造注入,比如上面ExDropDownList 的例子,创建ExDropDownList 实例不是我们的framework能够控制的。需要设值注入来协助。

我们怎么做的呢?把ExDropDownList的provider定义为静态属性,然后在Application_BeginRequest事件赋值
DataSourceProvider provider = new DataSourceProvider();
ExDropDownList.dataSourceProvider = provider;

这属于代码配置

用ExDropDownList 的例子来说明IoC不太恰当,因为ExDropDownList不是我们的framework能够完全控制的。除了IoC这种解耦方法外还有别的方法比如在config文件定义哪一个Assembly可以提供GetDataSource服务,或者我们定义一个ServicesFind类,它知道怎么样可以得到我们所需的IDataSourceProvider实例。

IoC现在看来,主要是用来解决接口参数的注入。framework可以根据很简单的约定,将不同组件组装起来,IoC不是新的事物,也不是哪一种语言的特有功能,只是一种组件的协作和组织方式。


如何更好的理解IOC和AOP

如何理解spring中的IOC和AOP 怎么说才会让面试官觉得你很牛
  • lpx6604895
  • lpx6604895
  • 2016年03月28日 14:07
  • 1006

Spring IOC容器启动过程

IOC容器启动过程 资源定位(classpath,filesystem等) 载入,将bean定义转换为内部数据结构BeanDefintion 向IOC容器注册bean 资源定位定位配置文件,通过Bea...
  • sichenglain
  • sichenglain
  • 2016年12月18日 13:41
  • 552

IOC三种注入方法解释

IOC三种注入方法解释 IoC模式最权威的总结和解释,应该是Martin Fowler的那篇文章“Inversion of Control Containers and the Depe...
  • xiaoxing1521025
  • xiaoxing1521025
  • 2013年04月24日 18:21
  • 1754

spring中为什么要使用IOC

开篇前言 在前面的博文中,小编主要简单的介绍了spring的入门知识,随着学习的深入,我们知道spring最核心的两大技术,IOC和AOP,这两个技术也是spring最耀眼的地方,在后续的博文中...
  • sdmxdzb
  • sdmxdzb
  • 2016年08月04日 16:14
  • 2761

自己动手编写IOC框架

转自: http://www.cnblogs.com/rongdi/p/4122289.html?utm_source=tuicool&utm_medium=referral终于到了激动人心的时刻了...
  • d12345678a
  • d12345678a
  • 2016年12月28日 16:26
  • 338

IOC和DI本质理解

IoC   IoC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性   1、为什么需要IoC容器 1.1、应用...
  • cws1214
  • cws1214
  • 2016年08月04日 13:29
  • 2158

各大主流.Net的IOC框架性能测试比较

在上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor、微软企业库中的Unity、Spring.NET、Str...
  • andyhebear
  • andyhebear
  • 2015年07月28日 10:06
  • 878

谈谈Spring中的IOC和AOP概念

IOC和AOP是Spring中的两个核心的概念,下面谈谈对这两个概念的理解。 --------------------------------------------------- 1. IOC(I...
  • eson_15
  • eson_15
  • 2016年04月07日 22:19
  • 18894

IOC容器注解方式详细解析

注解方式可以简化spring的IOC容器的配置!   使用注解步骤:          1)先引入context名称空间                    xmlns:context="h...
  • miachen520
  • miachen520
  • 2016年08月14日 16:56
  • 670

简单理解IOC和AOP的原理

IOC,依赖倒置的意思, 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B。 所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调...
  • linxijun120903
  • linxijun120903
  • 2017年02月22日 15:55
  • 5485
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IoC
举报原因:
原因补充:

(最多只允许输入30个字)