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

可是在现实的编程世界中,我们只能怎么才能实现控制反转呢?这时依赖注入(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. debug配置

  2. try-catch-finally 规则( 异常处理语句的语法规则 )

    1)  必须在 try 之后添加 catch 或 finally 块.try 块后可同时接 catch 和 finally 块,但至少有一个块. 2) 必须遵循块顺序:若代码同时使用 catch 和 ...

  3. (数组)Largest Rectangle in Histogram(栈解问题)

    Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...

  4. GTXE_COMMON

    http://forums.xilinx.com/xlnx/board/crawl_message?board.id=IMPBD&message.id=9657 If you are usin ...

  5. Eclipse遇坑记录

    1.安装Ivy插件 插件地址:http://ant.apache.org/ivy/ivyde/download.cgi 在线安装提示成功,但是配置窗口并未显示Ivy相关配置,随后利用手动安装重启即可 ...

  6. Spring MVC 简介

  7. spring aop实现权限管理

    问题源于项目开发 最近项目中需要做一个权限管理模块,按照之前同事的做法是在controller层的每个接口调用之前上做逻辑判断,这样做也没有不妥,但是代码重复率太高,而且是体力劳动,so,便有了如题所 ...

  8. D3.js 之 d3-shap 简介(转)

    [转] D3.js 之 d3-shap 简介 译者注 原文: 来自 D3.js 作者 Mike Bostock 的 Introducing d3-shape 译者: ssthouse 联系译者: 邮箱 ...

  9. epoll简介

    1.epoll简介 epoll是I/O事件通知工具,与select/poll相比,epoll最大的好处在于它不会随着监听fd数目的增长而效率降低.epoll API既可以用作edge触发的接口,也可以 ...

  10. ubuntu - 14.04,安装rpm程序!!

    一,安装rpm转deb的工具“alien”:在软件中心里面输入“alien”,看是否已经安装,如果没有安装则直接安装. 二,把rpm转换为deb:在shell里输入“sudo alien --scri ...