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思想
回顾简单工厂 回顾:从接口的角度去理解简单工厂模式 前面说到了简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子 ...
随机推荐
- Python学习笔记 - 函数参数
>>> def power(x): ... return x * x ... >>> power(5) 25 >>> def power(x, n ...
- Dynamics CRM 修改自定义实体名字及属性前缀(架构名称)
本文章以2013为例(2011同理,4.0比较简单直接在系统设置的自定义中设置即可). 1.设置-->自定义项-->发布者,下图中的红框内的即为需要设置的前缀. 2.设置-->解决方 ...
- 【一天一道LeetCode】#24. Swap Nodes in Pairs
一天一道LeetCode系列 (一)题目 Given a linked list, swap every two adjacent nodes and return its head. For exa ...
- 对MBProgressHUD第三方进行源码分析
GitHub源码地址,及时更新:iOS-Source-Code-Analyze MBProgressHUD是一个为iOS app添加透明浮层 HUD 的第三方框架.作为一个 UI 层面的框架,它的实现 ...
- Linux下实现秒级定时任务的两种方案(crontab 每秒运行)
第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command sleep XX //间隔秒数 done 第二种方案,使用crontab ...
- 03_Nginx添加新模块
1 进入nginx安装目录,查看nginx版本及其编译参数: [root@localhost nginx]# ./nginx -V nginx version: nginx/1.8.0 buil ...
- cocos2d-x 游戏开发之有限状态机(FSM) (一)
cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...
- eclipse或者AS链接手机真机之后,logcat里面日志信息乱跳
乱跳的日志信息不会对应用产生影响,但是它会影响视觉,影响查看logcat.那主要原因在哪里呢 ? 这是由于手机里面,正在的运行的进程太多导致的.^_^ 因此课件添加过滤器的作用之大. 对了,在logc ...
- objective-c中的method swizz实现"猴打补丁"
ruby中的猴打补丁很好实现,下面给出例子: class String alias :org_upcase :upcase def upcase puts("trace me if you ...
- 数据结构---栈C语言实现
#include <stdio.h> #include <stdlib.h> #define uchar unsigned char #define uint unsigned ...