1. 程式人生 > >C# Ioc、DI、Unity、TDD的一點想法和實踐

C# Ioc、DI、Unity、TDD的一點想法和實踐

stc 映射 rac 下載 性能 ole HA manager 單元

面向對象設計(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文件實現,也不知道有沒有更好地辦法)。

C# Ioc、DI、Unity、TDD的一點想法和實踐