2017年3月2日 星期四

Unity 入門 (5)



前篇,這次要說明如何用組態檔來設定 Unity 容器的型別對應。


先前的幾個範例,都是以程式碼來設定 Unity 的型別對應關係,這種以程式碼來設定元件組態的方式(Code as Configuration)只是 Unity 的其中一種用法。官方說明文件對此作法有另一個稱呼,叫作「執行時期組態」(run-time configuration)。

相對於執行時期組態,Unity 也有提供設計時期組態(design-time configuration)的作法,也就是利用組態檔來完成相關設定。這種作法的最大好處就是調整設定時只需修改組態檔,而不用重新編譯程式。

Unity 的組態設定是放在 .NET 標準的應用程式組態檔案裡,因此是以 XML 格式來編寫。在使用 Unity 組態 API 時,我們的專案至少要加入下列組件參考:

  • System.Configuration
  • Microsoft.Practices.Unity.Configuration

除此之外,程式中也要引用(using)下列命名空間:

  • Systmtem.Configuration
  • Microsoft.Practices.Unity
  • Microsoft.Practices.Unity.Configuration

然後,我們就能夠在程式中呼叫 Unity 容器的擴充方法 LoadConfiguration 來從組態檔載入相關設定。例如:

?
1
2
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();

LoadConfiguration 方法會從 .NET 應用程式組態檔中載入 Unity 相關組態,並且設定容器物件。

TIP  若使用 NuGet 來為專案加入 Unity 套件,NuGet 會自動幫你加入必要的組件參考。
接著當然就是撰寫組態檔了。在應用程式組態檔案中,我們得先加入一個自訂區段,以指定要用哪個類別來剖析 Unity 組態內容。這個自訂區段的名稱是「unity」,如下:

?
1
2
3
4
5
<configSections>
  <section name="unity"
           type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration"/>
</configSections>

接著我們可以再加入一個 unity 組態區段,把 Unity 相關設定寫在這個區段裡。以先前的範例來說,組態內容會是:

?
1
2
3
4
5
6
7
<unity>
  <namespace name="UnityDemo01" />
  <assembly name="UnityDemo01" />
  <container>
    <register type="ISayHello" mapTo="SayHelloInChinese" />
  </container>
</unity>

其中的 register 元素就是用來設定介面與實作類別的對應關係。由於前面已經有先用 namespace 元素宣告了命名空間的名稱,所以在 register 元素中的型別名稱就不用寫全名。

接著修改應用程式的進入點,也就是 Main 函式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
using System.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
  
namespace UnityDemo01
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            container.LoadConfiguration();
            ISayHello hello = container.Resolve<ISayHello>();
            hello.Run();
        }
    }
}

你可以看到,其中只有用到抽象型別 ISayHello,而沒有任何實作類別,完全是針對介面來寫程式。(呼~終於走到這一步啦!)

執行結果跟先前看過的範例一樣:




執行時期組態 vs. 設計時期組態

雖然用組態檔來控制介面與實作類別的對應有其方便之處──無須重新編譯程式碼就能抽換實作類別──但它也不是沒有缺點。相較於利用程式碼來設定組態的作法,組態檔比較容易出錯,而且可能更不好維護。至於不利維護,這點恐怕就見仁見智了。我總覺得 XML 格式不利人眼閱讀,尤其當組態檔越長越大時。

因此,最好只有在真的需要不重新編譯程式就任意抽換類別的情況才使用組態檔;其餘的場合,還是優先考慮使用程式碼來設定型別對應。這裡特別強調「真的需要」,是因為我們有時候會不加思索地將所有東西一股腦兒塞進組態檔案裡,或者認為「任何東西都可以隨時抽換就是最好最彈性的作法。」其實這都值得商榷。

當然,執行時期組態(Code as Configuration)和設計時期組態(XML 組態檔)這兩種作法並不互相排斥,它們是可以一起搭配運用的。例如我們可以將大部分的型別對應都以程式碼來設定,而少數需要隨時任意切換的類別則放在組態檔案裡。這是一種搭配方式。

還有一種更靈活的搭配。還記得上一篇提過的「後來居上原則」嗎?利用此特性,你可以用程式碼來設定所有的型別對應關係,之後再接著呼叫載入 XML 組態的方法。這會讓 XML 組態設定蓋掉原先程式碼的設定,而且是只有重複的部分才蓋掉,對於 XML 組態沒有涵蓋的部分,仍然會使用程式碼的設定。相反地,如果有些型別對應是絕對不允許別人透過組態檔亂改的,就可以在程式中先載入 XML 組態,然後才呼叫 RegisterType 方法來註冊這些型別。

小結

五篇筆記不算多,但是對於入門來說,我想應該差不多足夠了。當然,Unity 還有更多進階功能和用法,若要繼續深入,可以接著了解 Unity 如何管理物件的生命週期

Unity 入門系列就先寫到這裡吧!

from : http://huan-lin.blogspot.com/2012/07/unity-5.html

沒有留言:

張貼留言