C# Ioc、DI、Unity、TDD的一点想法和实践

catzhou 2018-05-17 原文

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(1);
            Assert.AreEqual(ret, true);
            ret = l.Init(2);
            Assert.AreEqual(ret, false);
            ret = l.Init(-1);
            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文件实现,也不知道有没有更好地办法)。

 

发表于 2018-05-17 00:36 毛毛虫 阅读() 评论() 编辑 收藏

 

版权声明:本文为catzhou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/catzhou/p/9048966.html

C# Ioc、DI、Unity、TDD的一点想法和实践的更多相关文章

  1. C 2013笔试题

    C 2013笔试题 1、把整数分解成素数 如90=2*3*3*5 【见2015年】 方法一: int main […]...

  2. ASP.NET Core MVC 视图

    ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处,学习难度较低。以下内容主要 […]...

  3. C#中的线程池使用(一)

    1  线程池的概念 许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生。其他线程 […]...

  4. 易语言效率与C++究竟差多少(质数和计算)

    易语言作为款主打 中文 易用 编程的开发软件。但是很多人都在批评易语言的效率。 我们今天通过 质数和计算 来看 […]...

  5. c++:一个辅助类让内存泄漏现原形!

    对于c++而言,如何查找内存泄漏是程序员亘古不变的话题;解决之道可谓花样繁多。因为最近要用到QT写程序,摆在我 […]...

  6. 多线程编程学习笔记——异步操作数据库

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 […]...

  7. 单链队列实现及基本操作

          #include<iostream>using namespace std; type […]...

  8. C# 枚举

    一、简介 枚举是一组命名整型常量;枚举类型是使用 enum 关键字声明的;C# 枚举是值类型。 二、语法 枚举 […]...

随机推荐

  1. 深度学习笔记

    这个是在公众号中看到的,提供一个笔记。 从深度学习基础、卷积网络和循环网络三个方面介绍该笔记。 深度学习基础 […]...

  2. Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow ——Chapter 1 Machine Learning Landscape

    1.Machine Learning概念: 提到机器学习,很多人会想到机器人管家、终结者等一些不着边际,高大上 […]...

  3. 如何在命令行中进入一个目录?

    打开命令行“Win+R”,输入“cmd”回车进入命令界面,在输入“D:”进入D盘,在输入cd空格adb_too […]...

  4. SpringBoot(十)_springboot集成Redis

    Redis 介绍 Redis是一款开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存也可持久 […]...

  5. 常用的Firefox浏览器插件、Chrome浏览器插件收藏

    [血的教训] 不要去下载“Firefox中国版(谋智网络)”,默认情况下会给你安装好多的莫名其妙的插件,推荐去 […]...

  6. (一) Mybatis源码分析-解析器模块

    Mybatis源码分析-解析器模块 原创-转载请说明出处 1. 解析器模块的作用 对XPath进行封装,为my […]...

  7. JavaEE理解

     JAVAEE和JAVASE只是概念上的分类,两种都由JDK提供开发工具(类),JDK包含所有JAVASE的A […]...

  8. 五十款阿里开源软件说明介绍

    阿里巴巴的Github代码托管地址:https://github.com/alibaba 通过写这篇文章从开源 […]...

展开目录

目录导航