依赖注入DI
说AOP不得不提依赖注入,先来看看一个实例。通过实例来解释依赖注入和它的用途。
我们现在要设计一个关于衣服的上架功能,有时候需要进行促销,我们现在知道的促销方式有打1折,和打2折。
最初的方案:
public class Cloth { ; public IRebate rebate = new OneRebate(); public decimal GetPrice() { return OneRebate(); } private decimal OneRebate() { return price * Convert.ToDecimal(0.1); } private decimal TwoRebate() { return price * Convert.ToDecimal(0.2); } }
控制台代码,
class Program { static void Main(string[] args) { Cloth c = new Cloth(); string value = c.GetPrice().ToString(); Console.WriteLine(value); Console.Read(); } }
不错,我们改动GetPrice()方法就可以调换不同的促销方式了。
过了几天,我们需要一个新的促销,3折的折扣。我们开始动工了,改改衣服类添加个3折的促销方法,再来改Main方法,调用3折的优惠,完工。
再后来我们要4折、5折、6折.. 你是不是开始躁了。而且这样的设计违背了开放封闭原则,每次改动都需要改Cloth类,修改方法。
这时我们来试试依赖注入,我们来改下之前的方案,
促销接口:
/// <summary> /// 促销接口 /// </summary> public interface IRebate { decimal MakeRebate(decimal price); }
然后实现折扣接口实现1折类和2折类:
/// <summary> /// 1折 /// </summary> public class OneRebate:IRebate { public decimal MakeRebate(decimal price) { return price * Convert.ToDecimal(0.1); } }
/// <summary> /// 2折 /// </summary> public class TwoRebate:IRebate { public decimal MakeRebate(decimal price) { return price * Convert.ToDecimal(0.2); } }
衣服类:
public class Cloth { ; public IRebate rebate; public decimal GetPrice() { return rebate.MakeRebate(price); } }
控制台代码:
class Program { static void Main(string[] args) { Cloth c = new Cloth(); c.rebate = new OneRebate(); string value = c.GetPrice().ToString(); Console.WriteLine(value); Console.Read(); } }
现在,我们添加新的促销,不用再修改之前的Coloth,而是填加新的促销类,并继承促销接口。在客户端实例化需要的促销方式就可以调用新的促销了。
什么是依赖注入?依赖注入好处在哪里?
来看看什么是依赖注入,很简单我们只是在Cloth里添加了一个接口,让客户端来实例化这个接口,从而调用不同的促销类。也就是让业务逻辑来决定如何实例化。
好处就是依赖注入很好的遵循了开放封闭原则。你会说,"我裤子都脱了,你就让我看这个?",我想说是的,但是这个原则的意义却很重要。
依赖注入实现有哪些方式?
1、setter注入,也就是实例中的方法,申明一个接口作为属性,客户端直接赋值。
2、构造函数注入,这种方式只不过是申明一个构造函数,让客户端在创建Cloth实例的时候就初始化促销类。用这种方式可以限制客户端必须创建促销类,我个人比较提倡这种方式,让代码更容易理解。
扩展
我们虽然实现了依赖注入,但是当我们换新的促销方式的时候是不是很麻烦?每次都要修改Main()方法,去实例化不同的促销。
spring.net框架为我们很好地解决了这个问题,
先引用spring组件,添加配置文件
<?xml version="1.0" encoding="utf-8" ?> <objects xmlns='http://www.springframework.net' default-autowire="byName"> <object id="rebate" type="spring.net.TwoRebate,spring.net"/> <object id ="Cloth" type="spring.net.Cloth,spring.net"/> </objects>
修改控制台代码:
class Program { static void Main(string[] args) { XmlApplicationContext applicationContext = new XmlApplicationContext("XMLFile1.xml"); Cloth c = (Cloth)applicationContext.GetObject("Cloth"); string value = c.GetPrice().ToString(); Console.WriteLine(value); Console.Read(); } }
当需要用OneRebate促销是,只用修改配置文件就可以了。spring.net的使用就不详细解释了,可以参考spring.net的文档或百度了解一下。有需要的话可以留言交流
依赖注入DI的更多相关文章
- [Android]使用Dagger 2依赖注入 - DI介绍(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...
- 浅析“依赖注入(DI)/控制反转(IOC)”的实现思路
开始学习Spring的时候,对依赖注入(DI)——也叫控制反转(IOC)—— 的理解不是很深刻.随着学习的深入,也逐渐有了自己的认识,在此记录,也希望能帮助其他入门同学更深入地理解Spring.本文不 ...
- 依赖注入(DI)和Ninject,Ninject
我们所需要的是,在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用.这种“需要”,就称为DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,I ...
- 控制反转IOC与依赖注入DI
理解 IOC http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例 的http:// ...
- Atitit js中的依赖注入di ioc的实现
Atitit js中的依赖注入di ioc的实现 全类名(FQCN)为标识符1 混合请求模式1 使用类内 builder 即可..2 Service locator method走ok拦2 Jav ...
- 控制反转(Ioc)和依赖注入(DI)
控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...
- 控制反转IOC与依赖注入DI【转】
转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...
- 依赖注入(DI)和控制反转(IOC)
依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...
- MVC进阶之路:依赖注入(Di)和Ninject
MVC进阶之路:依赖注入(Di)和Ninject 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类, ...
- 依赖注入(DI)和Ninject
[ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject 本文目录: 1.为什么需要依赖注入 2.什么是依赖注入 3.使用NuGet安装库 4.使用Ninject的一般步骤 5. ...
随机推荐
- mysql 数据库插入语句之insert into,replace into ,insert ignore
近期才发现mysql的插入语句竟然有如此多的使用方法,这里拿来分享一下. ①关于insert into : insert into table_name values(); insert into t ...
- vs2012 + web api + OData + EF + MYsql
vs2012 + web api + OData + EF + MYsql 开发及部署 先说下我的情况,b/s开发这块已经很久没有搞了,什么web api .MVC.OData都只是听过,没有实际开发 ...
- 【百度地图API】当地址解析失败时,如何调用search方法查找地址
原文:[百度地图API]当地址解析失败时,如何调用search方法查找地址 有个朋友问我,当地址解析失败时,应该如何处理呢?比如,他想搜索“南宁市青秀区”. --------------------- ...
- Emojicon - 为你提供emoji表情的整套方案
Github : https://github.com/rockerhieu/emojicon 事实上国内的<表情大全>也有提供类似整套表情解决方式,并且还支持gif表情:http://w ...
- 基于tomcat为了应对高并发模型实现webserver
在博客上,一个简单的AIOweb来样加工.查看AIO异步处理,依靠操作系统完成IO操作Proactor处理模型确实很强大,它可以实现高并发.高响应server一个很好的选择,但在tomcat中间con ...
- 多线程学习之五超时模式Timer
timed[超时模式]案例:一个线程提供下载数据,另一个线程执行下载,如果有5秒钟以上,提供下载的线程没有提供数据,下载线程因超时异常,停止下载线程运行. 超时异常类 /** * */ package ...
- 一个简单的创建dom的函数
var regName = /^(div|a|p|ul|li|input|select|document|body|iframe)$/;function createDom(name, obj) { ...
- Ubuntu10.04中间Leach协议一键安装
半天后,尝试,引用网络上的零散资源,成品博客Leach协议ubuntu10.04在安装(12.04也可以在右侧安装,然而,实施效果的不,求解决~~),并制作了补丁. 一个关键的安装步骤如下面: 1.在 ...
- HBuilder CSS 自定义代码块
=begin 本文档是CSS代码块的编辑文件.注意不要把其他语言的设置放到css里来. HBuilder可使用ruby脚本来编辑代码块和增强操作命令. 1.编辑代码块 如果要新增一个代码块,复制如下一 ...
- 让apache2不开机启动,管理Ubuntu的开机启动项
今天在网上发现了一个很好用的管理Ubuntu下开关启动的软件,叫做sysv-rc-conf 使用命令行: tf@ubuntu:/etc/apache2$ sudo update-rc.d -f apa ...