依赖注入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. ...
随机推荐
- 教你一步一步部署.net免费空间OpenShift系列之三------上传ASP.net程序
接上回书,创建应用后,我们如何将自己的ASP.Net部署到应用空间呢,这里用WinSCP的SFTP协议进行上传和下载 上传ASP.net程序 下载WinSCP,并打开PuTTYGen 点击Genera ...
- 数据传输对象(DTO)介绍及各类型实体比较
数据传输对象(DTO)介绍及各类型实体比较 本文将介绍DDD分层架构中广泛使用的数据传输对象Dto,并且与领域实体Entity,查询实体QueryObject,视图实体ViewModel等几种实体进行 ...
- Swift语言指南(九)--基本运算符
原文:Swift语言指南(九)--基本运算符 运算符(operator)是用来检查,改变或合并值的一种特殊符号或短语.例如,加号运算符让两个数字相加(如:let i = 1 + 2),还有些更复杂的运 ...
- ThinkPHP框架设计与扩展总结
详见:http://www.ucai.cn/blogdetail/7028?mid=1&f=5 可在线运行查看效果哦 导言:ThinkPHP框架是国内知名度很高应用很广泛的php框架,我们从一 ...
- angularJS之使用过滤器转化输出 (angularJS系列最后一篇)
在视图模板中使用过滤器 过滤器也是一种服务,负责对输入的内容进行处理转换,以便更好地向用户显示. 过滤器可以在模板中的{{}}标记中使用: {{ expression | filter:arg1:ar ...
- leetcode -day31 Subsets I II
1. Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a ...
- c语言mysql api
原文:c语言mysql api 1.mysql_affected_rows() //返回上次UPDATE.DELETE或INSERT查询更改/删除/插入的行数. 2.mysql_ ...
- 快速构建Windows 8风格应用11-语义缩放
原文:快速构建Windows 8风格应用11-语义缩放 本篇博文主要介绍为什么需要语义缩放.什么是语义缩放.如何构建语义缩放. 为什么需要语义缩放 如果用过Windows 8系统的开发者都知道在Win ...
- 项目笔记---CSharp图片处理
原文:项目笔记---CSharp图片处理 项目笔记---CSharp图片处理 最近由于项目上需要对图片进行二值化处理,就学习了相关的图片处理上的知识,从开始的二值化的意义到动态阀值检测二值化等等,并用 ...
- 小公司免费的ERP软件
http://www.2bizbox.cn/ https://www.odoo.com/