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思想
回顾简单工厂 回顾:从接口的角度去理解简单工厂模式 前面说到了简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子 ...
随机推荐
- shell的date命令:使用方法,以及小时、分钟的计算
shell命令格式严格,不像python那样命令行中可以添加空格.如等号两边无空格.有多余空格错误,日期date命令就是最明显的例子. 命令格式: date [-u] [-d datestr] [-s ...
- Java集合之Map
Map架构: 如上图: (1)Map是映射接口,Map中存储的内容是键值对(key-value) (2)AbstractMap是继承于Map的抽象类,实现了Map中的大部分API. (3)Sorted ...
- 禁用JavaScript控制台调试
原文链接: Disable the User's JavaScript Console 原文日期: 2014年03月06日 翻译日期: 2014年03月07日 翻译人员: 铁锚 有几个巨头公司,即Fa ...
- 【Qt编程】Qt学习笔记<二>
1. QApplication类和QWidget类都包含在QtGui模块中.所以我们可以只包含这个头文件即可. 2. 在c++中,用new分配了内存空间就需要用delete来释放空 ...
- DigitalClock的替代者TextClock
DigitalClock在API 17(Android4.2)中就被官方定义为过时的方法,很奇怪为什么现在很多的网上的帖子都介绍DigitalClock方法的使用(已经过时),如果你想让自己的应用在高 ...
- x265 (HEVC编码器,基于x264) 介绍
x265要出来了.简单翻译了一下项目网站首页的介绍. x265是一个开源项目,是一个将视频编码为h.265/高效率的视频编码(HEVC)格式的免费的库,在GNU GPL条款下发布.它的源代码是免费提供 ...
- SpriteBuilder代码中弱引用(weak)需要注意的地方
比如在GameScene类中有一个弹出菜单层实例的引用,我们有: @implementation GameScene{ //other ivars __weak GameMenuLayer *_pop ...
- Centos下grep命令简介
grep命令简介 grep 是一个最初用于Unix操作系统的命令行工具.在给出文件列表或标准输入后,grep会对匹配一个或多个正则表达式的文本进行搜索,并只输出匹配(或者不匹配)的行或文本. grep ...
- BP 神经网络
BP(Back Propagation)网络是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一.BP ...
- Oracle Global Finanicals Technical Reference(一)
Skip Headers Oracle Global Finanicals Oracle Global Financials Technical Reference Manual Release 11 ...