Unity Application Block 1.2 學習筆記

mpsky發表於2021-09-09

應用場景:隨便給一些數字,要求對這些數字進行一項基本的資料運算(例子中只實現了加法/乘法)

先新增對Microsoft.Practices.Unity.dll的引用

準備測試用的介面和類:

/// 


/// 介面
 /// 

    public interface Icalculate
    {
        int Calculate(params int[] a);

        double Calculate(params double[] a);

        string GetOperationName();

        
    }

    /// 
    /// 加法運算
    /// 

    public class Addtive : Icalculate
    {
        /// 
        /// 注意:至少要有一個建構函式,否則用配置檔案方式Resolve時會提示:Icalculate是一個介面,沒有建構函式,所以不能建立例項云云,但有趣的是用硬編碼方式卻可以成功
        /// 

        public Addtive() { }

        public int Calculate(params int[] a)
        {
            int Result = 0;

            foreach (int x in a)
            {
                Result += x;
            }

            return Result;
        }

        public double Calculate(params double[] a)
        {
            double Result = 0.0;

            foreach (double x in a)
            {
                Result += x;
            }

            return Result;
        }

        public string GetOperationName()
        {
            return "加法";
        }
    }

    /// 
    /// 乘法運算
    /// 

    public class Multiplication : Icalculate
    {

        public Multiplication() { }

        public int Calculate(params int[] a)
        {
            int Result = 1;

            foreach (int x in a)
            {
                Result *= x;
            }

            return Result;
        }

        public double Calculate(params double[] a)
        {
            double Result = 1.0;

            foreach (double x in a)
            {
                Result *= x;
            }

            return Result;
        }

        public string GetOperationName()
        {
            return "乘法";
        }
    }

    /// 
    /// (四則)運算管理器
    /// 

    public class CalcManager
    {
        private Icalculate _calc;


        public CalcManager(Icalculate IC)
        {
            _calc = IC;
        }

        //[InjectionMethod]
        //public void SetCalculate(Icalculate IC) {
        //    _calc = IC;
        //}

        public void Compute(params int[] a)
        {
            string _paramName = "";

            foreach (int x in a)
            {
                _paramName += x.ToString() + ",";
            }
            _paramName = _paramName.Trim(',');

            Console.WriteLine("{0} {1}計算結果:{2}", _paramName, _calc.GetOperationName(), _calc.Calculate(a));
        }

        public void Compute(params double[] a)
        {
            string _paramName = "";

            foreach (double x in a)
            {
                _paramName += x.ToString() + ",";
            }
            _paramName = _paramName.Trim(',');

            Console.WriteLine("{0} {1}計算結果:{2}", _paramName, _calc.GetOperationName(), _calc.Calculate(a));
        }

    }
為了對比,我們先用傳統方式來呼叫試下:

static void Main(string[] args)
{
    #region 不用依賴注入的傳統方式
    CalcManager CM = new CalcManager(new Addtive());
    CM.Compute(1, 2, 3, 4, 5);//計算1,2,3,4,5的和

    //CM = new CalcManager(new Multiplication());
    //CM.Compute(1, 2, 3, 4, 5);//計算1,2,3,4,5的乘積
    #endregion            

    Console.ReadLine();
}

雖然簡單易懂,但細想一下可擴充套件性並不高,如果以後又增加了除法,平方,減法...等一系列演算法,不是每次都要這一段程式碼嗎?原因就是介面,演算法實體類,呼叫程式之間的耦合性太高接下來,我們用Unity換一種寫法:

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;

static void Main(string[] args)
{
    

    #region 使用依賴注入(硬編碼方式)
    IUnityContainer container = new UnityContainer();
    container.RegisterType() //注入加法類
         .RegisterType();//注入管理器            


    CalcManager CM = container.Resolve();//取得CalcManager的例項
    CM.Compute(1.1, 2.9, 3.1, 4, 5);

    //container.RegisterType();//繼續注入乘法類

    //CM = container.Resolve();
    //CM.Compute(1, 2, 3, 4, 5);
    #endregion

    

    Console.ReadLine();
}

單從程式碼上看,只不過換了種寫法和思路,但仍然屬於“硬編碼”的方式,如果要增加其它演算法或換成其它演算法,一樣還是要改這段程式碼.(貌似純屬瞎折騰?呵呵)下面切入正題,Unity除了這種硬編碼方式,還允許把注入規則/對映寫到配置檔案裡先修改App.Config,內容大致如下:圖片描述

  
    


  
  

同時再新建一個config目錄,把DI.config檔案放在該目錄下,內容:圖片描述

  
    
    
    
    
  

  
    
      
              
        <!--結實驗,下面這一行加不加程式都能執行,只要確保CalcManager中有一個引數為Icalculate的構架函式或(注入)設定方法就行[參看CalcManager中註釋掉的部分],Unity在這一點上確實比較“智慧”--&gt
               
      

    

  


呼叫程式碼再換一種寫法:

static void Main(string[] args)
{
    
    #region 使用依賴注入(配置檔案方式)
    IUnityContainer container = new UnityContainer();
    UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
    section.Containers.Default.Configure(container);

    CalcManager CM = container.Resolve();
    CM.Compute(1, 2, 3, 4, 5);
    #endregion

    Console.ReadLine();
}

這回仔細看下,程式碼中已經完全找不到Addtive,Multiplication等這些具體的類名了,整個程式完全依賴於配置檔案中的相關節點(其實OO的角度來講,是基於介面Icalculate的程式設計以及不同物件的組合讓這一切成為可能)。如果我們要把乘法運算換成加法運算,太容易了,把DI.config中的    換成原來的呼叫程式碼一行都不用改!最後:Unity除了實現IOC/DI之外還有一些其它用途,比如:實現單件模式(而且這種實現方式更靈活,比如我們可以讓任何一個普通的類,在容器的生命週期內僅返回一個例項,這是傳統的單件模式中"把類硬編碼定死為單件例項"無法做到的)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1806/viewspace-2801275/,如需轉載,請註明出處,否則將追究法律責任。

相關文章