C# Ioc、DI、Unity、TDD的一点想法和实践
面向对象设计(OOD)有助于我们开发出高性能、易扩展以及易复用的程序。其中,OOD有一个重要的思想那就是依赖倒置原则(DIP)。
依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)
控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)
依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)
IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)、
Unity:是微软推出的IOC框架
TDD:测试驱动开发,是敏捷开发中的一项核心实践和技术,也是一种设计方法论
上面的内容都是抄的(英文不好,放在这里备查),相关的内容看了一些,不明觉厉。
曾经写了一个酒店读写房卡的程序,不同的酒店门锁是不一样的,同一个酒店也有可能更换门锁,程序流程:
1.通过Api获取当前酒店的门锁类型
2.如果需要则下载对应门锁的dll
3.实现读写功能
一、定义接口
新建一个类库(Lock.Interface),代码如下:
namespace Lock
{
public interface ILock
{
/// <summary>
/// 门锁初始化
/// </summary>
/// <param name="password">初始化密码</param>
/// <returns></returns>
bool Init(int password); }
}
是不是算是IoC了?(我不确定)
二、单元测试
新建一个单元测试项目(Lock.Tests),代码如下:
1.门锁A单元测试
/// <summary>
/// 门锁A测试
/// </summary>
[TestClass()]
public class LockATests
{
/// <summary>
/// 初始化,password为正奇数
/// </summary>
[TestMethod()]
public void InitTest()
{
ILock l = new LockA();
var ret = l.Init();
Assert.AreEqual(ret, true);
ret = l.Init();
Assert.AreEqual(ret, false);
ret = l.Init(-);
Assert.AreEqual(ret, false);
} }
2.门锁B单元测试
/// <summary>
/// 门锁B测试
/// </summary>
[TestClass()]
public class LockBTests
{
/// <summary>
/// 初始化测试,password为正偶数
/// </summary>
[TestMethod()]
public void InitTest()
{
ILock l = new LockB();
var ret = l.Init(1);
Assert.AreEqual(ret, false);
ret = l.Init(2);
Assert.AreEqual(ret, true);
ret = l.Init(-1);
Assert.AreEqual(ret, false);
}
显然编译都不能通过(不能通过编译也是一种测试)
三、定义类
1.创建门锁A类库(Lock.LockA),代码如下:
/// <summary>
/// 门锁A
/// </summary>
public class LockA : ILock
{ /// <summary>
/// 初始化
/// </summary>
/// <param name="password">正确密码是正奇数</param>
/// <returns></returns>
public bool Init(int password)
{
return password > 0 && (password % 2) == 1;
}
}
2.创建门锁B类库(Lock.LockB),代码如下:
/// <summary>
/// 门锁B
/// </summary>
public class LockB : ILock
{
/// <summary>
/// 初始化
/// </summary>
/// <param name="password">正确密码是正偶数</param>
/// <returns></returns>
public bool Init(int password)
{
return password > 0 && (password % 2) == 0;
}
}
分别编译成功后,回到测试项目,添加引用,编译通过,运行测试:

算不算TDD?
四、主程序
1.添加控制台项目
2.添加Unity(5.8.6)包
3.修改App.Config为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration, Version=5.2.1.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f" />
<!--上一些的内容网上复制过来有错误,后来查看UnityConfigurationSection的定义,复制了对应的程序集
type="命名空间.类名,程序集"
-->
</configSections>
<unity>
<containers>
<container name="LockA">
<register type="Lock.ILock,Lock.Interface" mapTo="Lock.LockA,Lock.LockA" ></register>
</container>
<container name="LockB">
<register type="Lock.ILock,Lock.Interface" mapTo="Lock.LockB,Lock.LockB"></register>
</container>
</containers>
</unity>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
4.引用接口
5.Main方法如下:
static void Main(string[] args)
{
var container = new UnityContainer();
UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
config.Configure(container, "LockA");
ILock l = container.Resolve<ILock>();
Console.WriteLine(l.Init(2));
Console.WriteLine(l.Init(1));
Console.WriteLine(l.Init(-1));
Console.ReadKey();
}
6.复制门锁A的dll复制到运行目录
7.运行结果如为:False、True、False,是门锁A的结果
8.将“LockA”改成“LockB”,并将门锁B的dll复制到运行目录,运行结果为True、False、False是门锁B的结果
算DI吧?咱都用了Unity了。
至此,基本实现了想要的功能,未来新酒店要增加门锁C、门锁D都没问题,只有老酒店改成门锁E的问题没解决(估计可以通过动态修改config文件实现,也不知道有没有更好地办法)。
C# Ioc、DI、Unity、TDD的一点想法和实践的更多相关文章
- 关于依赖注入IOC/DI的感想
之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...
- spring ioc DI 理解
下面是我从网上找来的一些大牛对spring ioc和DI的理解,希望也能让你对Spring ioc和DI的设计思想有更进一步的认识. 一.分享Iteye的开涛对Ioc的精彩讲解 Ioc—Inversi ...
- .Net IOC 之Unity
.Net IOC 之Unity 在码农的世界里,为了应付时常变更的客户需求,增加的架构的客扩展性,减少工作量.IOC诞生了,它是一种可以实现依赖注入和控制对象生命周期的容器.最为一个有节操.有追求的码 ...
- ASP.NET MVC IOC之Unity攻略
ASP.NET MVC IOC之Unity攻略 一.你知道IOC与DI吗? 1.IOC(Inversion of Control )——控制反转 即依赖对象不在被依赖模块的类中直接通过new来获取 先 ...
- IOC容器Unity的使用及独立配置文件Unity.Config
[本段摘录自:IOC容器Unity 使用http://blog.csdn.net/gdjlc/article/details/8695266] 面向接口实现有很多好处,可以提供不同灵活的子类实现,增加 ...
- Spring系列(二):Spring IoC/DI的理解
这几天重新学习了一下Spring,在网上找了相关的ppt来看,当看到Spring IoC这一章节的时候,先大致浏览了一下内容,有将近50页的内容,内心窃喜~QAQ~,看完这些内容能够对IoC有更深层次 ...
- 设计模式之初识IoC/DI(六)
本篇和大家一起学习IoC和DI即控制反转和依赖注入. 当然听上去这词语非常的专业,真不知道是怎么组出来的,看上去难归看上去难,但稍微理解一下也就这么回事了. 首先我们要明白IoC/DI干嘛用的,不然别 ...
- AutoFac IoC DI 依赖注入
AutoFac IoC DI 依赖注入 记录点点滴滴知识,为了更好的服务后来者! 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌 ...
- 设计模式——从工厂方法模式到 IOC/DI思想
回顾简单工厂 回顾:从接口的角度去理解简单工厂模式 前面说到了简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子 ...
随机推荐
- (八)喜马拉雅Demo引出的细节(代理模式和图片缩放)
喜玛拉雅是一款电台APP,界面非常美观,通过模仿这一APP学习到很多细节. 1.图片导入后有些框内不全如何补全: 寻常的办法是再准备一张图片拖入,比较好的办法是右击已经导入的图片选择Show in F ...
- 【Matlab编程】Matlab及Java小时钟
一年前曾经用matlab的gui做了一个时钟,由于是直接用GUIDE和ActiveX控件写的,程序虽说有许多行,大多数都是自动生成的,自己写的只有十几行而已.闲着没事,就耗费了下午的时间用matlab ...
- Oracle E-Business Suite Maintenance Guide Release 12.2(Patching Procedures)
更多内容参考: http://docs.oracle.com/cd/E51111_01/current/acrobat/122ebsmt.zip Preparing for Patching For ...
- TCP连接建立系列 — 服务端发送SYNACK段
本文主要分析:服务器端如何构造和发送SYNACK段. 内核版本:3.6 Author:zhangskd @ csdn blog 发送入口 tcp_v4_send_synack()用于发送SYNACK段 ...
- iOS自定义多参数类型方法
前几天做自定义UIAlertView的时候,想仿造系统自带的初始化方法做一个AlertView,里面涉及到不确定多参数的设置和使用问题.这里做一下记录. 我自定义了一个方法: - (instancet ...
- Android 图片加载库Glide 实战(二),占位符,缓存,转换自签名高级实战
http://blog.csdn.net/sk719887916/article/details/40073747 请尊重原创 : skay <Android 图片加载库Glide 实战(一), ...
- OpenCV——去雾
这是一个简化的实现算法,完整的算法请参考: Single Image Haze Removal Using Dark Channel Prior --CVPR 2009 // define head ...
- javascript访问html元素的内容(2)
对于(1)中最后一个包装方式创建的是一个方法,我们必须以方法调用的方式来使用它,这和其他默认的以属性返回结果略有不同,如果有强迫症的童鞋有些伤不起,那么我们下面就把它实现为属性返回的方式: //chi ...
- 全局程序集缓存GAC
GAC中的所有的Assembly都会存放在系统目录"%winroot%\assembly下面.放在系统目录下的好处之一是可以让系统管理员通过用户权限来控制Assembly的访问. 目录:C: ...
- spring 整合 mybatis 中数据源的几种配置方式
因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下. 一.采用org.mybatis.spring.mapp ...