2018年8月20日 星期一

使用 Autofac 進行建構式注入並且數值或者字串與解析時候,需要覆蓋當初註冊數值或者字串用法

使用 Autofac 進行建構式注入並且數值或者字串與解析時候,需要覆蓋當初註冊數值或者字串用法

當我們在使用 Autofac IoC Container 的時候,我們具體實作的類別內建構式需要傳入數值或者字串的時候,我們可以使用這三種方法來進行宣告 : NamedParameter , TypedParameter , ResolvedParamet ;另外,當我們進行解析的時候,我們也想要覆蓋之前註冊所定義的數值或字串,上面所述的三種方式來進行覆蓋。
關於這兩項需求更詳盡的使用說明,可以查看官方 Passing Parameters to Register / Passing Parameters to Resolve 文件。
在這篇文章中,我們將要來說明如何再進行 DI 容器註冊與解析的時候,如何透過 NamedParameter 來解決需要注入的數值與字串的需求。這篇文章的範例原始碼,可以從 https://github.com/vulcanlee/CSharpNotes2018/tree/master/AutofacResolveParameter 取得
我們首先宣告一個 IMessage 介面,並且設計一個 ConsoleMessage 類別來實作這個介面,不過,在這個 ConsoleMessage 具體實作類別中,僅有設計一個建構式,這個建構式需要傳入一個字串與一個整數數值。
所以,當我們使用 ContainerBuilder.RegisterType 方法進行抽象介面與具體實作類別的註冊需求的時候,可以使用延伸方法 WithParameter 來指定建構式參數的明確數值是甚麼?其中延伸方法 WithParameter 的第一個參數將會是建構函式的參數名稱,第二個參數將會為指定參數名稱的實際數值。在我們這個範例中,我們具體實作類別的建構函式 public ConsoleMessage(string name, int age) ,他需要傳入一個字串與一個整數數值,因此,我們使用了 WithParameter("name", "Awesome") / WithParameter("age", 18) 來指定使用這兩個數值傳入到要注入物件的建構式內。因此,當我們透過 Autofac IoC Container 要注入 IMessage 這個介面的時候 (或者進行 container.Resolve<IMessage>() 手動解析時候),Autofac DI Container,將會把上面定義的兩個數值,傳入到建構式 public ConsoleMessage(string name, int age)
現在,我們要進行手動解析 IMessage 介面時候,不希望使用當初註冊宣告的數值,而希望使用我們另外提供的數值,讓 Autofac IoC 容器使用指定的數值,傳入到建構式內,建立一個具體實作類別的物件。此時,當我們呼叫 container.Resolve<IMessage> 方法的時候,可以在 Resolve 方法內,傳入 NamedParameter 物件,指定哪個參數名稱需要使用我們指定的數值來傳入到建構函式內,類似這樣的敘述 container.Resolve<IMessage>(new NamedParameter("name", "Oh..No"), new NamedParameter("age", 77));
C Sharp / C#
class Program
{
    static void Main(string[] args)
    {
        // 準備建立型別對應註冊的工作
        var builder = new ContainerBuilder();
        // 進行抽象型別與具體實作類別的註冊
        builder.RegisterType<ConsoleMessage>().As<IMessage>()
            .WithParameter("name", "Awesome")
            .WithParameter("age", 18);


        // 這裡將會建立 DI 容器
        IContainer container = builder.Build();

        // 進行抽象型別的具體實作物件的解析
        IMessage message = ;

        // 執行取得物件的方法
        message.Write("Hi Vulcan");

        // 進行抽象型別的具體實作物件的解析
        IMessage messageParameter = container.Resolve<IMessage>(
            new NamedParameter("name", "Oh..No"),
            new NamedParameter("age", 77));

        // 執行取得物件的方法
        messageParameter.Write("Hi Vulcan");

        Console.WriteLine("Press any key for continuing...");
        Console.ReadKey();
    }
}

public interface IMessage
{
    void Write(string message);
}

public class ConsoleMessage : IMessage
{
    string _Name;
    int _Age;
    public ConsoleMessage(string name, int age)
    {
        _Name = name;
        _Age = age;
    }
    public void Write(string message)
    {
        Console.WriteLine($"[{_Name}, {_Age}] 訊息: {message} 已經寫入到螢幕上了");
    }
}
現在,我們可以執行我們的專案,此時,將會出現底下的輸出結果,第一行是我們使用了 container.Resolve<IMessage>() 進行手動解析出來 IMessage 的具體實作類別的物件;而第二行將會為使用了 container.Resolve<IMessage>(new NamedParameter("name", "Oh..No"), new NamedParameter("age", 77)); 敘述,取得了另外一個物件,我們可以從這兩個輸出內容中看出,這兩個物件確實使用了不同的數值與字串,傳入到該具體實作類別的建構式。
[Awesome, 18] 訊息: Hi Vulcan 已經寫入到螢幕上了
[Oh..No, 77] 訊息: Hi Vulcan 已經寫入到螢幕上了
Press any key for continuing...

關於 Xamarin 在台灣的學習技術資源

Xamarin 實驗室 粉絲團
歡迎加入 Xamarin 實驗室 粉絲團,在這裡,將會經常性的貼出各種關於 Xamarin / Visual Studio / .NET 的相關消息、文章、技術開發等文件,讓您可以隨時掌握第一手的 Xamarin 方面消息。
Xamarin.Forms @ Taiwan
歡迎加入 Xamarin.Forms @ Taiwan,這是台灣的 Xamarin User Group,若您有任何關於 Xamarin / Visual Studio / .NET 上的問題,都可以在這裡來與各方高手來進行討論、交流。
Xamarin 實驗室 部落格
Xamarin 實驗室 部落格 是作者本身的部落格,這個部落格將會專注於 Xamarin 之跨平台 (Android / iOS / UWP) 方面的各類開技術探討、研究與分享的文章,最重要的是,它是全繁體中文。
Xamarin.Forms 系列課程
Xamarin.Forms 系列課程 想要快速進入到 Xamarin.Forms 的開發領域,學會各種 Xamarin.Forms 跨平台開發技術,例如:MVVM、Prism、Data Binding、各種 頁面 Page / 版面配置 Layout / 控制項 Control 的用法等等,千萬不要錯過這些 Xamarin.Forms 課程


沒有留言:

張貼留言