Unity Container 容器是一個輕量級,可擴展的相依性注入容器,這個相依性注入容器工具集現在已經開源了,若您想要更清楚了解 Unity 更多功能,可以參考 Unity Container on Github。
在這裡,我們將要來了解,如何透過 Unity 來實踐相依性注入的三種注入實作物件的方法:
- 建構式注入 Constructor Injection
- 屬性注入 Property Injection
- 方法注入 Method Injection
本篇文章的專案範例原始碼,可以從 https://github.com/vulcanlee/CSharpNotes2018/tree/master/UnityDI取得
建立練習專案
- 點選 Visual Studio 2017 功能表 [檔案] > [新增] > [專案]
- 當出現 [新增專案] 對話窗,點選 [已安裝] > [Visual C#] > [主控台應用程式] ,並且在最下方 [名稱] 欄位處,輸入 UnityDI ,作為此練習的開發專案名稱。
- 使用滑鼠右擊該專案節點,選擇 [管理 NuGet 套件] ,點選 [瀏覽] 標籤頁次,在搜尋文字輸入盒中,輸入
Unity
關鍵字。 - 當出現 Unity NuGet 套件之後,選擇這個套件,安裝到這個練習專案中
- 滑鼠雙擊 [Program.cs] 這個節點檔案,使用底下程式碼將其替換
- 在這裡,我們定義了兩個介面合約 IEmployee , ICompany
- 另外,我們實作 IEmployee 的具體類別 Employee,在這裡類別中,我們分別展示如何使用建構式注入、屬性注入、方法注入,因此,我們在這個實作類別中,定義了三個屬性 PropertyInjectionCompany , ConstructorInjectionCompany , MethodInjectionCompany
- 我們也實作 ICompany 的具體類別 Company,在這個類別的建構式內,我們將會顯示出當時產生物件的雜湊碼,透過了雜湊碼我們就可以區分出,再透過不同相依性注入而得到的物件,究竟是不是同一個執行個體。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Attributes;
namespace UnityDI
{
public interface IEmployee
{
void DisplaySalary();
}
public class Employee : IEmployee
{
[Dependency]
public ICompany PropertyInjectionCompany { get; set; }
public ICompany ConstructorInjectionCompany { get; set; }
public ICompany MethodInjectionCompany { get; set; }
[InjectionConstructor]
public Employee(ICompany tmpCompany)
{
ConstructorInjectionCompany = tmpCompany;
}
[InjectionMethod]
public void Initialize(ICompany tmpCompany)
{
MethodInjectionCompany = tmpCompany;
}
public void DisplaySalary()
{
PropertyInjectionCompany.ShowSalary();
ConstructorInjectionCompany.ShowSalary();
MethodInjectionCompany.ShowSalary();
Console.WriteLine($"Property Injection Object Hash Code is {PropertyInjectionCompany.GetHashCode()}");
Console.WriteLine($"Constructor Injection Object Hash Code is {ConstructorInjectionCompany.GetHashCode()}");
Console.WriteLine($"Method Injection Object Hash Code is {MethodInjectionCompany.GetHashCode()}");
}
}
public interface ICompany
{
void ShowSalary();
}
public class Company : ICompany
{
public Company()
{
Console.WriteLine($"Company Object Hash Code = {this.GetHashCode()}");
}
public void ShowSalary()
{
Console.WriteLine("你的薪水是 22 K");
}
}
class Program
{
static void Main(string[] args)
{
IUnityContainer unitycontainer = new UnityContainer();
unitycontainer.RegisterType<ICompany, Company>();
unitycontainer.RegisterType<IEmployee, Employee>();
IEmployee emp = unitycontainer.Resolve<IEmployee>();
emp.DisplaySalary();
Console.WriteLine("Press any key for continuing...");
Console.ReadKey();
}
}
}
建構式注入 Constructor Injection 的使用方式
在這裡,我們將我們所需要注入的物件介面,宣告成為該建構式的參數,例如
public Employee(ICompany tmpCompany)
在這裡,將會由 Unity Container 容器中,幫助我們自動產生出一個 ICompany 的實作物件,該注入的物件將會設定到 ConstructorInjectionCompany 屬性(當然,也可以是欄位 Field)中屬性注入 Property Injection 的使用方式
想要使用這個屬性注入的機制,我們需要在該類別中宣告這個介面屬性成員,例如
public ICompany PropertyInjectionCompany { get; set; }
,在這裡 PropertyInjectionCompany 這個屬性的型別就是 ICompany 這個介面;而為了要能夠讓 Unity Container 容器幫助我們自動注入 ICompany 的具體實作執行個體,所以,我們需要在這該屬性前面,使用 [Dependency]
屬性 (Attribute) 來標示出來,這樣,當這個物件被 Unity 解析與產生之後,該屬性也就會注入 ICompany 的實作類別之執行個體。方法注入 Method Injection 的使用方式
現在,我們宣告了一個方法
public void Initialize(ICompany tmpCompany)
在這方法需要一個 ICompany 參數,為了要能夠讓 Unity Container 容器知道要透過這個方法,幫助我們注入 ICompany 介面之具體實作類別的執行個體,我們可以在該方法前面,使用 [InjectionMethod]
這個 C# 屬性 (Attribute),這樣,就可以做到方法注入的功能了。進行測試
- 我們可以開始執行這個專案,您將會得到底下的內容
- 我們的主程式一開始將會建立一個 IUnityContainer 物件,在這裡,我們是建立出 UnityContainer 類別的執行個體
- 接著,我們透過了 IUnityContainer.RegisterType 方法,將介面與具體實作類別的型別名稱進行註冊的動作,這樣,Unity Container 容器,當要進行解析動作的時候,就會知道,甚麼樣的介面、型別,需要使用哪個具體型別來建立出實際的執行個體來使用。
- 當註冊完成之後,我們將會透過 IUnityContainer.Resolve 方法,解析出 IEmployee 介面的具體實作物件出來
- 透過解析出來的具體實作物件,我們將會呼叫該具體實作物件的 DisplaySalary 方法
Company Object Hash Code = 42750725
Company Object Hash Code = 49212206
Company Object Hash Code = 40256670
你的薪水是 22 K
你的薪水是 22 K
你的薪水是 22 K
Property Injection Object Hash Code is 49212206
Constructor Injection Object Hash Code is 42750725
Method Injection Object Hash Code is 40256670
Press any key for continuing...
進階閱讀
其他相關文章
更多關於 Xamarin / Xamarin.Forms 教學、技術分享、用法文章,請參考 I ♥ Xamarin