Ioc的实现及应用

来源:互联网 发布:php array push 编辑:程序博客网 时间:2024/05/17 03:57

什么是Ioc

什么是Ioc(Inversion of control),Ioc又叫DI(Dependency Injection),就是将你设计的类交给系统来控制,而不是你自己编码控制,这个应该是来源于java中的。做过j2ee开发的朋友肯定熟悉struts+hibernate+spring的结构。而spring正是为了实现Ioc而存在的,可想而知Ioc是多重要。当然我们不是在谈java而是在说.net,因为Ioc是一种思想而不是针对某种语言的。在.net中我们也是会经常碰到Ioc的,做.net开发的朋友肯定知道sprint.net、Castle等,这些都是优秀的Ioc框架。那么Ioc是做什么用的呢?

Ioc的作用

    Jon Tirsén 与 Aslak Hellesøy(PicoContainer的两位开发者)在2003年Java Polis的演讲经常被人们拿来讨论Ioc,其中的Kiss实例是人们说的最多的,这里举个和它类似的例子。

先看一下上图,如果现在我需要一个蛋糕,现在有几种方式可以实现。第一就是自己动手来做,第二就是我有朋友他做的比较好我拜托他帮我做,第三种就是我直接打电话给蛋糕房送货上门。刚好这三种方式也是我们设计三层架构时实现层间解耦方式的演变,我在图的下方已经标出来。三层架构中虽然我们在BLL调用DAL的时候(UI调用BLL也是如此)不是直接通过new来直接实例化的,但是在DALFactory和BLLFactory的内部还是是直接new一个对应实例来创建对象的,相当于自己没有直接做而是委托别人来做,但是有了Ioc之后工厂也就不需要那么麻烦了,可以直接拿现成了。 或许你还有些模糊,不过没关系,接着往下看,我们再具体些,看看下面这两幅图:

    比较一下这两幅图有什么异同点。这两幅图大部分都是相同的,不同点就是DALFactory和DAL之间不再耦合了,BLLFactory和BLL之间也不再耦合了,也就是说工厂和对应的层之间的耦合性降低了,当然了,这一切归功于Ioc。

    “抽象”的概念是非常重要的,但是不管怎么样抽象,到了最后还是需要具体实现。我们理想的状况就是具体对象的创建永远都不要出现在代码中,也就是说我们不要出现内部依赖,那怎么办呢?当然就是将内部依赖转移到外部依赖中去。依赖虽然是必须的,但是一旦将依赖由内部转移到外部就可以将该依赖注入到模块中,因此也叫“依赖注入”。

    如果按照上面第二幅图的做法,我们在工厂内部就不需要直接通过new来创建对应的实例了,而只需要通过一个字符串类型的名称从Ioc容器中获得然后转化为对应的接口类型就可以了。

自己实现Ioc

    说了那么多Ioc的优点,不如我们自己实现一个Ioc来对它彻底的认识。我们通过创建一个IocContainer来管理我们的DAL和BLL中的类,由于IocContainer在项目中需要大量使用,为了节省开销我们采用单例模式。我们在IocContainer的构造函数中读取xml文件(我们将DAL及BLL中的类的信息写到xml文件中,这样方便我们管理)然后利用反射实例化所有的类,接着将这些实例放到IDicrectory中,为了方便我们找到这些实例,我们建立一个索引器。这样一来我们在工厂中就不需要通过new来创建这些类了,而是直接到我们的容器中直接去取,这样工厂也不再和对应的层耦合了。好了,道理比较简单,就是利用反射原理(其实对于像Sprint.net和Castle这样的框架也是如此)直接来看源代码吧(我们仍然以登录为例,其他代码跟另外一篇博客“传统三层架构”中完全相同就不再贴出来):

先看看配置文件IocContainer.xml:

再看看IocContainer.cs:

好了,看看如何使用,以DALFactory为例(BLLFactory一样),这也是我们进行解耦的核心(上面那些是为这一步打基础),我们的面向接口编程通过下面的代码就可以完全反映出来,就从我们在下面的代码中没有看到UserAccess就可说明DALFactory已经不再依靠DAL了,他们之间已经没有耦合性了:

 

主要代码就上面这些,道理在上面也已经说的很明白了。为了方便查看将源代码提供给大家:Ioc.rar