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#净化版WebApi框架

    前言 我们都知道WebApi是依赖于Asp.Net MVC的 ,所以,想创建WebApi,就需要先创建一个As […]...

  2. c# Invalidate() Update() Refresh()的区别 – siso

    c# Invalidate() Update() Refresh()的区别 Control.Invalidat […]...

  3. C# 多维数组 交错数组的区别,即 [ , ] 与 [ ][ ]的区别

    多维数组的声明 在声明时,必须指定数组的长度,格式为 type [lenght ,lenght ,lengh, […]...

  4. C# 合并及拆分PDF文件

    C# 合并及拆分PDF文件 有时我们可能会遇到下图这样一种情况 — 我们需要的资料或教程被分成了几部分存放在多 […]...

  5. 【Visual Studio调教小记录】C++指针靠前靠后??

    教你如何在VS中选择`int* a`还是`int *a` 本文地址:https://www.cnblogs.c […]...

  6. Unity正交相机智能包围物体(组)方案

    Unity正交相机智能包围物体(组)方案 目录 Unity正交相机智能包围物体(组)方案 一、技术背景 二、相 […]...

  7. C# ——计算线性关系kb值、R平方,类似于excel的趋势线线性关系功能

    这些功能Excel上都有,原理一模一样,现在需要C#的实现代码;各函数的线性拟合,相关系数、截距为0(即强制过 […]...

  8. 协同过滤算法中皮尔逊相关系数的计算 C++

    template <class T1, class T2>double Pearson(std:: […]...

随机推荐

  1. 用Go自己实现配置文件热加载功能

    说到配置文件热加载,这个功能在很多框架中都提供了,如beego,实现的效果就是当你修改文件后,会把你修改后的配 […]...

  2. vue2.0 在华为手机等手机自带浏览器打开白屏的问题

    使用vue2.0 开发的单页面网站,  在华为部分型号(p20也是….),部分安卓手机打开页面是空 […]...

  3. 带你了解CSRF和XSS(二)

    什么是CSRF?     CSRF(Cross-site request forgery)跨站请求伪造,也被称 […]...

  4. Writeup:第五届上海市大学生网络安全大赛-Web

    目录 Writeup:第五届上海市大学生网络安全大赛-Web 一、Decade 无参数函数RCE(./..) […]...

  5. MySQL查询这一篇就够了

    1. 条件 使用where子句对表中的数据筛选,结果为true的行会出现在结果集中 语法如下: select […]...

  6. 『Candies 差分约束系统』

    差分约束系统 我们先来认识一下差分约束系统鸭! 差分约束系统是一种特殊的\(n\)元一次不等式组,它包含了\( […]...

  7. iframe 自适应高度的多种实现方式

    iframe高度自适应内容 需求:实现 iframe 的自适应高度,能够随着页面的长度自动的适应以免除页面和 […]...

  8. JSONP跨域

    1.浏览器的同源策略 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔 […]...

展开目录

目录导航