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

控制反转IOC, 全称 “Inversion of Control”。依赖注入DI, 全称 “Dependency Injection”。

面向的问题:软件开发中,为了降低模块间、类间的耦合度,提倡基于接口的开发,那么在实现中必须面临最终是有“谁”提供实体类的问题。(将各层的对象以松耦合的方式组织起来,各层对象的调用面向接口。)

当一个类的实例需要另一个类的实例协助时,在传统的程序设计过程中,通常有调用者来创建被调用者的实例。

然后,采用依赖注入原则,创建被调用者的实例的工作不再由调用者完成,而是由IOC容器来完成,这就是“控制反转”的意思,然后,将其注入调用者,因此也称为 “依赖注入”。

Martin Fowler,在其著名的文章《Inversion of Control Containers and the Dependency Injection pattern》中将具体依赖注入划分为三种形式,即构造器注入、属性(设置)注入和接口注入。

习惯将其划分为一种(类型)匹配和三种注入:

  • 类型匹配(Type Matching):虽然我们通过接口(或者抽象类)来进行服务调用,但是服务本身还是实现在某个具体的服务类型中,这就需要某个类型注册机制来解决服务接口和服务类型之间的匹配关系;
  • 构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象。如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前解析注册的依赖关系并自行获得相应参数对象;
  • 属性注入(Property Injection):如果需要使用到被依赖对象的某个属性,在被依赖对象被创建之后,IoC容器会自动初始化该属性;
  • 方法注入(Method Injection):如果被依赖对象需要调用某个方法进行相应的初始化,在该对象创建之后,IoC容器会自动调用该方法

创建一个控制台程序,定义如下几个接口(IA、IB、IC和ID)和它们的实现类(A、B、C、D)。在类型A中定义了三个属性B、C和D,其参数类型分别为IB、IC和ID。

其中,

属性B作为构函数的参数,认为它会以构造器注入的方式被初始化 (??);

属性C应用了DependencyAttribute特性,意味着这是一个需要以属性注入方式被初始化的依赖属性;

属性D则通过方法Initialize初始化,该方法上应用了特性InjectionMethodAttribute, 意味着这是一个方法注入,在A对象被Ioc容器创建的时候,D会被自动调用。

Microsoft有一个轻量级的IoC框架Unity, 支持构造器注入,属性注入,方法注入。对于C#语言,由于语法元素上本身较其他语言丰富许多,如何实施注入还有些技巧和特色之处。

下面介绍如下:

测试类:

namespace UnityDemo
{
    public interface IA { }
    public interface IB { }
    public interface IC { }
    public interface ID { }

    public class A : IA
    {
        public IB B { get; set; }

        [Dependency]
        public IC C { get; set; }
        public ID D { get; set; }

        public A(IB b)
        {
            this.B = b;
        }

        [InjectionMethod]
        public void Initialize(ID d)
        {
            this.D = d;
        }
    }

    public class B : IB { }
    public class C : IC { }
    public class D : ID { }
}

配置注册:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
    </configSections>
    <unity>
        <containers>
            <container name="defaultContainer">
                <register type="UnityDemo.IA, UnityDemo" mapTo="UnityDemo.A, UnityDemo"/>
                <register type="UnityDemo.IB, UnityDemo" mapTo="UnityDemo.B, UnityDemo"/>
                <register type="UnityDemo.IC, UnityDemo" mapTo="UnityDemo.C, UnityDemo"/>
                <register type="UnityDemo.ID, UnityDemo" mapTo="UnityDemo.D, UnityDemo"/>
            </container>
        </containers>
    </unity>

    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

Main方法中,创建一个Ioc容器的UnityContainer对象,并加载配置信息对其初始化,然后调用它的泛型的Resolve方法创建一个实现了泛型接口IA的对象。

最后将返回对象转换成类型A, 并逐一检验B,C和D属性是否为空,即初始化情况。

namespace UnityDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            var configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
            configuration.Configure(container, "defaultContainer");

            A a = container.Resolve<IA>() as A;
            if (null != a)
            {
                Console.WriteLine("a.B==null? {0}", a.B == null ? "Yes" : "No");
                Console.WriteLine("a.C==null? {0}", a.C == null ? "Yes" : "No");
                Console.WriteLine("a.D==null? {0}", a.D == null ? "Yes" : "No");
            }

        }
    }
}

执行结果:

分别体现了接口注入、构造器注入(属性B)、属性注入(属性C)和方法注入(属性D)。

JACK D. @ NJ USA

时间: 2024-08-06 15:40:55

控制反转(Ioc)和依赖注入(DI)的相关文章

iOS控制反转(IoC)与依赖注入(DI)的实现

背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大的方便,要在OC上较好的实现这两个功能,需要一些小小的技巧. 控制反转和依赖注入 控制反转 简单来说,将一个类对象的创建由手动new方式改为从IOC容器内获取,就是一种控制反转,例如我们现在要创建一个ClassA类,则常规方法为 ClassA *a = [ClassA new]; 如果使用控制反转,

控制反转IOC与依赖注入DI

1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针.分针和秒针顺时针旋转,从而在表盘上产生正确的时间.图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务.我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组

控制反转IOC与依赖注入DI - 理论篇

学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现,毕竟是之前的好同事,好朋友,我也就抽时间百度了很多资料 在查阅网上资料的过程中,我发现大多技术篇幅都是IOC的代码实现,并没有一篇介绍IOC理论的篇幅!这显然不是我想要的. 我知道要想搞明白IOC,就必须要弄明白什么是IOC(控制反转)?为什么叫IOC(控制反转)?为什么之后又可以称为DI(依赖注

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

1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理.所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. IoC是一个很大的概念,可以用不同的方式来实现.其主要实现方式有两种:<1>依赖查找(Dependency Lookup):容器提供回调接口和上下文环

spring中的控制反转IoC和依赖注入DI

原文:http://blog.163.com/[email protected]/blog/static/50639037200721345218382/ IoC(Inversion of Control),这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关 系.这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好.qq 号.电话号.手机号.

Spring入门--控制反转(IOC)与依赖注入(DI)

    1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理.所谓的"控制反转"概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. IoC是一个很大的概念,可以用不同的方式来实现.其主要实现方式有两种:<1>依赖查找(Dependency Lookup)

AutoFac (控制反转IOC 与依赖注入DI)

绝世好文  转:http://blog.csdn.net/fanbin168/article/details/51293218 1 IOC概念(很重要) 项目 先引入AutoFac 和AutoFac MVC两个程序集到项目中 然后我们在MVC(UI层)的App_Start文件夹下创建一个AutoFacConfig.cs类 [csharp] view plain copy using System; using System.Collections.Generic; using System.Li

控制反转IOC的依赖注入方式

引言: 项目中遇到关于IOC的一些内容,因为和正常的逻辑代码比较起来,IOC有点反常.因此本文记录IOC的一些基础知识,并附有相应的简单实例,而在实际项目中再复杂的应用也只是在基本应用的基础上扩展而来的.本文目的两个,一是记录学习过程,以便将来温故:二是请大牛对小弟指点一二. 概念: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. 控制反转一般分为两种类型,依赖注入(Dependen

依赖耦合、解耦、控制反转(IOC)、依赖注入

随着net的深入学习,出现了很多概念性的东西需要理解,现在统一记录一下. 1.依赖:现阶段在任何一个有请求作用的系统,都会出现A类调用B类的情况,这时候A类就依赖于B类,A类和B类存在依赖关系. 2.耦合.解耦:A类依赖于B类,这时对B类调用,一般通过A a=new B();的形式,不过这个时候如果B类重构(例如:增加了一个参数param1),要保证A类的正确使用,则必须重新new:A a=new B(param1); 则此时A类和B类就是耦合关系.不过带来了很多的不方便之处,如果B类频繁变动,