原文:C#依赖注入控制反转IOC实现详解

IOC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。

举个例子,组件A中有类ClassA,组件B中有接口IB和其对应的实现类B1和B2。

那么,现在ClassA需要利用IB接口来做一些事情,例如:

public class ClassA {
public void DoSomething() {
IB b = ???
b.DoWork();
}
}

现在的问题来了,IB b = ??? 中这三个???要写什么代码?是要写成 IB b = new B1(),还是要写成IB b = new B2() ?

不管是哪一种,都会让ClassA强依赖于IB的实现。

在上面这种方案中,ClassA通过new一个B1或B2来实现对IB的依赖的获取,换句话说,ClassA在主动获取依赖。

这样的设计会让ClassA很难扩展,那我们要改良设计:使用依赖注入。上面说到了,问题出在new这里,也就是依赖是Class去主动获取的,那我们就要解决这个问题:不要去主动获取对IB的依赖(通过new),而让这个依赖从ClassA的外面“注入”进来。注入有多种方式,比较常用的一种是通过构造函数注入,那么,我们要把ClassA改成:

public class ClassA {
private IB b;

public ClassA(IB b) {
this.b = b;
}

public DoSomething() {
this.b.DoWork();
}
}

可以看到,通过把IB这个依赖从构造函数中“注”进来后,ClassA就不依赖IB的实现了。还可以发现,这个重构过程中,我们是把"ClassA主动获取对IB的依赖”变成“把对IB的依赖从外部注入到ClassA中”,依赖的方向反转了,所以,依赖注入又称“控制反转”。

IoC框架(如Unity, Autofac,Spring.Net),其中Unity是微软自己封装的,另外可以利用Extnesions.Dependency动态生成类(参考之前的将RFCTable转为List<T>利用依赖注入动态生成类的例子),参考之前的代码

下面以Unity作为介绍:

Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入。Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题。构建一个成功应用程序的关键是实现非常松散的耦合设计。下面介绍一下c#中使用unity的方法(我是以webapi项目为例,但本例中并没有针对webapi做特殊处理)

新建一个mvc4 webapi项目,下面的例子只用到get方法

用nuget安装unity,如图

新建一个接口类,以及继承该接口的两个类

直接在api/values的get中尝试简单实现unity

using (IUnityContainer container = new UnityContainer())

{

container.RegisterType<IBook, BBook>();

IBook a = container.Resolve<IBook>();

var strResult = a.Write();

return strResult;

}

然后在浏览器中查看,页面显示的返回值,是BBook的

如果container.RegisterType<IBook, BBook>();中的BBook改为ABook,返回值就是ABook的内容

config中代码如下

在configSections中加入

<section name="unity"

type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />

在configuration中加入

<unity  xmlns="http://schemas.microsoft.com/practices/2010/unity">

<container>

<register type="testunity.Models.IBook,testunity" mapTo="testunity.Models.ABook, testunity" />

</container>

</unity>

注意 type="testunity.Models.IBook,testunity" mapTo="testunity.Models.ABook, testunity"

testunity.Models.IBook是命名空间加类名

testunity是程序集的名称

然后cs的代码改成

using (IUnityContainer container = new UnityContainer())

{

UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

configuration.Configure(container);

IBook a = container.Resolve<IBook>();

var strResult = a.Write();

return strResult;

}

在浏览器中可以看到返回结果对应的是config中register的那个类

每次调用都要写IUnityContainer container = new UnityContainer()显然不是好办法

那就把container封装到一个单列类中

简单实现如下

public class ServiceLocator:IServiceProvider

{

private readonly IUnityContainer _container;

private static readonly ServiceLocator instance = new ServiceLocator();

private ServiceLocator()

{

UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

_container = new UnityContainer();

section.Configure(_container);

}

public static ServiceLocator Instance

{

get { return instance; }

}

public object GetService(Type serviceType)

{

return _container.Resolve(serviceType);

}

public T GetService<T>()

{

return _container.Resolve<T>();

}

}

cs代码修改如下

IBook a = ServiceLocator.Instance.GetService<IBook>();

var strResult = a.Write();

return strResult;

C#依赖注入控制反转IOC实现详解的更多相关文章

  1. Helloworld之Spring依赖注入/控制反转(DI/IoC)版

    Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...

  2. PHP关于依赖注入(控制反转)的解释和例子说明

    PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12)   阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...

  3. Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转

    原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...

  4. Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转

    小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...

  5. laravel5.2总结--服务容器(依赖注入,控制反转)

    1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...

  6. 依赖注入&控制反转

    IoC——Inversion of Control  控制反转DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...

  7. Spring 依赖注入控制反转实现,及编码解析(自制容器)

    定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...

  8. 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入

    系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...

  9. MVC 依赖注入/控制反转

    http://www.cnblogs.com/cnmaxu/archive/2010/10/12/1848735.html http://www.cnblogs.com/artech/archive/ ...

随机推荐

  1. JS数据类型的转换规则

    数据类型转换的规则 1 如果只有一个值,判断这个值是真还是假,遵循只有0,NaN,'',null,undefined这五个是假的,其余的都是真 2 如果是两个值比较是否相等,遵循以下规则: ![]-& ...

  2. javascript中的事件问题的总结

    一.什么是事件? 事件就是DOM和浏览器之间的交互行为(只要触发了这个行为,也就相当于触发了事件),我们可以通过事件监听来绑定事件,例如:box.onclick=function(){},如果我们点击 ...

  3. 学习笔记:Vue——混入

    前言: 到现在用Vue做了不少项目了,用到的都是初阶的功能,很多高阶能力都没有用到.仅用初级阶段也能做项目,甚至是复杂项目,可见vue之强大,果然是渐进式开发方式. 但是本着虚心学习的态度,还是要抽空 ...

  4. (转)Oracle RAC日常管理命令

    转自:http://www.xuebuyuan.com/1206937.html 一.查看RAC环境 RAC架构,2节点信息 节点1 SQL> show parameter instance N ...

  5. HDU 5237 Base64

    Base64 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...

  6. SpringMVC学习记录(五)--表单标签

    在使用SpringMVC的时候我们能够使用Spring封装的一系列表单标签,这些标签都能够訪问到ModelMap中的内容. 以下将对这些标签一一介绍. 1.引入标签头文件 在正式介绍SpringMVC ...

  7. 第二次作业:对Github的初步学习应用(四则运算的自动生成C#实现)

    GIT地址  https://github.com/Anzerl?tab=repositories GIT用户名  Anzerl 学号后五位  062426 博客地址  https://www.cnb ...

  8. Ajax之旅(二)--XMLHttpRequest

         上文中提到的Ajax的异步更新.主要使用XMLHttpRequest对象来实现的,XMLHttpRequest对象能够在不向server提交整个页面的情况下,实现局部更新网页. 当页面所有载 ...

  9. swift开发网络篇—利用NSURLConnection GET请求和POST请求

    一.GET请求和POST请求简单说明 @IBOutlet weakvar userName:UITextField! @IBOutletweakvar userPwd:UITextField! @IB ...

  10. TensorFlow on Windows: “Couldn't open CUDA library cudnn64_5.dll”

    TensorFlow on Windows: "Couldn't open CUDA library cudnn64_5.dll" 在 windows 下,使用 import te ...