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实现详解的更多相关文章
- Helloworld之Spring依赖注入/控制反转(DI/IoC)版
Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...
- PHP关于依赖注入(控制反转)的解释和例子说明
PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12) 阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...
- Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转
原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...
- Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转
小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...
- laravel5.2总结--服务容器(依赖注入,控制反转)
1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...
- 依赖注入&控制反转
IoC——Inversion of Control 控制反转DI——Dependency Injection 依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...
- Spring 依赖注入控制反转实现,及编码解析(自制容器)
定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...
- 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入
系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...
- MVC 依赖注入/控制反转
http://www.cnblogs.com/cnmaxu/archive/2010/10/12/1848735.html http://www.cnblogs.com/artech/archive/ ...
随机推荐
- GO语言学习(八)Go 语言常量
Go 语言常量 常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier ...
- 挖一挖不经常使用到而又非常有用的重载-Split
Split这个基本上全部的程序开发者都用到,一般使用单字符和长字符串拆分字符串的较多.事实上另一个重载很好用.那就是多种组合字符来进行拆分. 比如: "aaaaaaaaaa{@}bbbbbb ...
- thinkphp事务不能回滚的问题(因为助手函数)
thinkphp事务不能回滚的问题(因为助手函数) 一.总结 二.thinkphp 5 事务不能回滚 Db::startTrans(); try{ db('address')->where([' ...
- CNTK 搞深度学习-1
CNTK 搞深度学习 Computational Network Toolkit (CNTK) 是微软出品的开源深度学习工具包.本文介绍CNTK的基本内容,如何写CNTK的网络定义语言,以及跑通一个简 ...
- ITFriend开发日志20140611
原文链接:http://www.itfriend.cn/user/ITFriend/article/details/100274 1.调整登录页. 把大背景图,改为通用的banner图,节省流量. 登 ...
- vue项目中一些文件的作用
原文 简书原文:https://www.jianshu.com/p/38749e5bec3c 大纲 1.vue项目结构 2.主要的配置文件 2.1.package.json 2.2.dev-serve ...
- JNI——Java调用C/C++函数
从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java.C/C++的桥梁——JNI.哈哈!分享一下! 一.简介 JNI是Java native interface的简 ...
- 数据类型总结——String(字符串类型)
相关文章 简书原文:https://www.jianshu.com/p/546a755c3eb6 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...
- Asp 使用 Microsoft.XMLHTTP 抓取网页内容无乱码处理,并过滤须要的内容
Asp 使用 Microsoft.XMLHTTP 抓取网页内容.并过滤须要的内容 Asp 使用 Microsoft.XMLHTTP 抓取网页内容无乱码处理,并过滤须要的内容 演示样例源代码: < ...
- [Http] Understand what an HTTP Request is
Let's look at several HTTP requests to learn the basic structure of these messages, and how the vari ...