举例:在每天的日常生活中,我们离不开水,电,气。在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭。而城市化之后,人们从这些琐事中解放了出来,城市中出现了水厂,发电厂,燃气公司。水,电,气我们自己打开开关用就可以而不用关心这些都是怎么来的,怎么实现的。控制反转指的就是由我们自己提供水电气发展为由政府提供水电气的整个过程。

可是在现实的编程世界中,我们只能怎么才能实现控制反转呢?这时依赖注入(DI: Independence Inject)出场了。依赖注入主要分为构造函数, 属性注入和依赖方法注入,注入。下面通过Unity框架对三种方式分别进行了实现:

电厂接口:IElectricity

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
interface IElectricity
{
string ProvideElectricity();
}
}

电厂类:ElectricityFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
class ElectricityFactory:IElectricity
{
public string ProvideElectricity()
{
return "The electricity is coming!";
}
}
}

水厂接口:IWater

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
interface IWater
{
string ProvideWater();
}
}

水厂类:WaterFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
class WaterFactory:IWater
{
public string ProvideWater()
{
return "The water is coming!";
}
}
}

人接口(人会用水,用电):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
public interface People
{
string UsingWater();
string UsingElectricity();
}
}

居民类(用构造函数,属性注入,依赖方法注入,三种方式分别对居民用水,用电方法进行的具体实现):

using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
#region 构造器注入
class ResidentsA:People
{
WaterFactory _wf;
ElectricityFactory _ef;
public ResidentsA(WaterFactory wf,ElectricityFactory ef)
{
this._ef = ef;
this._wf = wf;
}
public string UsingWater()
{
Console.WriteLine("I want to drink!");
return _wf.ProvideWater();
} public string UsingElectricity()
{
Console.WriteLine("I want to cook some food!");
return _ef.ProvideElectricity();
}
}
#endregion #region 属性注入
class ResidentsB : People
{
//属性注入
[Dependency]
public IWater _w { set; get; }
[Dependency]
public IElectricity _e { set; get; } public string UsingWater()
{
Console.WriteLine("I want to drink!");
return _w.ProvideWater();
} public string UsingElectricity()
{
Console.WriteLine("I want to cook some food!");
return _e.ProvideElectricity();
}
}
#endregion #region 依赖方法注入
class Residents : People
{
public IWater _iw;
public IElectricity _ie; public string UsingWater()
{
Console.WriteLine("I want to drink!");
return _iw.ProvideWater();
} public string UsingElectricity()
{
Console.WriteLine("I want to cook some food!");
return _ie.ProvideElectricity();
} [InjectionMethod]
public void UsingWaterTest(IWater iw)
{
Console.WriteLine("I want to drink!");
this._iw = iw;
} [InjectionMethod]
public void UsingElectricityTest(IElectricity ie)
{
Console.WriteLine("I want to cook some food!");
this._ie = ie;
}
}
#endregion
}

App.config配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<!--register type="full class name,namespace"--> <register type="IOCTesting.IWater,IOCTesting" mapTo="IOCTesting.WaterFactory,IOCTesting">
<lifetime type="singleton"/>
</register> <register type="IOCTesting.IElectricity,IOCTesting" mapTo="IOCTesting.ElectricityFactory,IOCTesting">
<lifetime type="singleton"/>
</register> <!--<register type="IOCTesting.People,IOCTesting" mapTo="IOCTesting.ResidentsA,IOCTesting">
<lifetime type="singleton"/>
</register>-->
<!--<register type="IOCTesting.People,IOCTesting" mapTo="IOCTesting.ResidentsB,IOCTesting">
<lifetime type="singleton"/>
</register>-->
<register type="IOCTesting.People,IOCTesting" mapTo="IOCTesting.Residents,IOCTesting">
<lifetime type="singleton"/>
</register>
</container>
</unity>
</configuration>

具体的调用类Program.cs:

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace IOCTesting
{
class Program
{
static void Main(string[] args)
{
//配置文件注册
IUnityContainer mycontanier = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)System.Configuration.ConfigurationManager.GetSection("unity");
section.Configure(mycontanier); //创建调用者
//Console.WriteLine("-------------------Constructor Injection-------------------");
//ResidentsA pa = mycontanier.Resolve<People>() as ResidentsA;
//Console.WriteLine(pa.UsingWater());
//Console.WriteLine(pa.UsingElectricity()); //Console.WriteLine("-------------------Property Injection-------------------");
//ResidentsB pb = mycontanier.Resolve<People>() as ResidentsB;
//Console.WriteLine(pb.UsingWater());
//Console.WriteLine(pb.UsingElectricity()); Console.WriteLine("-------------------Method Injection-------------------");
Residents p = mycontanier.Resolve<People>() as Residents;
Console.WriteLine(p._iw.ProvideWater());
Console.WriteLine(p._ie.ProvideElectricity()); Console.ReadLine();
}
}
}

(备注:Unity框架需要提前自己安装,其实就是引用了两个包而已,在测试的过程中,如需测试构造函数注入,则需要在App.config和Program.cs中注释掉属性注入,依赖方法注入部分,否则会报错。)

ps. 1. 依赖方法注入会在被依赖对象创建时自动调用;

2. 由于被依赖对象是在程序运行时创建的所以这里面又用到了反射的技术,对于反射,我会继续创建反射的例子进行说明。

C# 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)的更多相关文章

  1. 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)

    举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...

  2. 个人对【依赖倒置(DIP)】、【控制反转(IOC)】、【依赖注入(DI)】浅显理解

    一.依赖倒置(Dependency Inversion Principle) 依赖倒置是面向对象设计领域的一种软件设计原则.(其他的设计原则还有:单一职责原则.开放封闭原则.里式替换原则.接口分离原则 ...

  3. 什么是控制反转(IoC)?什么是依赖注入(DI)?以及实现原理

    ​ IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良的程序.传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试:有了 ...

  4. 【Java_Spring】控制反转IOC(Inversion of Control)

    1. IOC的概念 控制反转IoC(Inversion of Control)是一种设计思想,而DI(依赖注入)是实现IoC的一种方法.在没有使用IOC的程序中,对象间的依赖关系是靠硬编码的方式实现的 ...

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

    控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...

  6. 依赖注入(DI)和控制反转(IOC)

    依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...

  7. 控制反转IOC与依赖注入DI【转】

    转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...

  8. IOC 控制反转(Inversion of Control,英文缩写为IoC)

    在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 在这样的齿轮组中,因为是协同工作,如果有一个齿轮出了问题,就可能会影响到整个齿 ...

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

    学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...

随机推荐

  1. 关于 block的一些浅识

    block的定义:“带自动变量的匿名函数” (一)写法: ^ void (int iAge){ NSLog(@"%d", iAge);}; 和C函数写法区别在于: 1) :以插入符 ...

  2. C++笔记--指针数组和结构

    指针 类型为T*的变量能保存一个类型T对象的地址 Char c=‘a’:Char * p=& c://保存了c的地址 指针的操作一般都是间接的引用,就是相当于引用指针所指的对象. 0是一个特殊 ...

  3. MySQL数据库简介

    数据库就是数据的集合. 关系数据库是一种特殊的数据库,它将数据组织成表,并表示为表之间的关系. 数据库系统往往是大型项目的核心数据内容,如银行的用户账户信息.腾讯的QQ用户账户信息.股市的各种交易信息 ...

  4. ObjectARX杂碎--(学习指南及书籍)

    ---------------------------------------------------------------------------------------------------- ...

  5. 点石成金:访客至上的网页设计秘笈(原书第2版) 中文PDF版

    可用性设计是Web设计中最重要也是难度最大的一项任务.本书作者根据多年从业的经验,剖析用户的心理,在用户使用的模式.为扫描进行设计.导航设计.主页布局.可用性测试等方面提出了许多独特的观点,并给出了大 ...

  6. Android手游外挂入侵----寓攻于守,方能破敌

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 手游外挂入侵 随着各种爆款手游的风靡,目前手机游戏的占比用户已经形成一个巨大的市场,市场上你争我夺,有将PC版本移植到手机中,也有新模式手游的推出. ...

  7. Flink on Yarn模式启动流程分析

    此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Flink On Yarn 架构 Paste_Image.png 前提条件首先需要配置YARN_CONF_DI ...

  8. 正经学C#_判断[IF语句]:[c#入门经典]

    判断语句几乎是最为常用的语句之一,是最有效的. 先说IF语句,IF语句也是属于分支的一种,用来控制流程的. IF的语句是这样的 IF(xxx 条件) { //代码块 } ,b; ) { b=a--; ...

  9. Python3中集合的混合使用

    比较简单没什么好说的: list_1 = [1,2,3,4,6,3,2,5,7,8,2,1] list_1 = set(list_1) list_1.add(999) list_2 = set([2, ...

  10. 【Java】Strategy Pattern

    前言 如果说,商场打折针对不同的时节,比如双十一.圣诞节.春节这些值得促销的好日子,进行不同程度的降价打折从而获得最大程度上的收益,如果有一群鸭子,只会游泳.嘎嘎叫,但是某一天某种类型的鸭子学会了飞, ...