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 課程


2018年8月19日 星期日

在 ASP.NET Core 專案內使用 Autofac 相依性注入 DI 容器

在 ASP.NET Core 專案內使用 Autofac 相依性注入 DI 容器

若使要在 ASP.NET Core 專案開發環境,將會使用 ASP.NET Core 內建的相依性注入容器功能用來在類別與其相依性之間達成控制權反轉 (IoC),不過,若您想要使用 Autofac DI Container 相依性注入容器來進行取代 ,也就是我們想要在開發 ASP.NET Core 專案的時候,能夠使用 Autofac 相依性注入容器來進行開發設計,首先,您需要安裝這個 Autofac.Extensions.DependencyInjection 套件( 因為,這個套件已經整合了 ASP.NET Core 的 Microsoft.Extensions.DependencyInjection 功能 ) 到您的 ASP.NET Core 專案內。
ASP.NET Core Autofac Nuget Package Install
ASP.NET Core Autofac Nuget Package Preview
接下來,我們需要打開 [Program.cs] 檔案節點,在 WebHost 之後,加入這個方法呼叫 .ConfigureServices(services => services.AddAutofac()),如底下程式碼所示;不過,您還需要加入 [Autofac.Extensions.DependencyInjection] 這個命名空間,以便可以使用 [AddAutofac] 這個方法。
C Sharp / C#
public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureServices(services => services.AddAutofac())
            .UseStartup<Startup>();
}
現在,我們需要打開 [Startup.cs] 這個檔案,在這個 Startup 類別內,加入底下這段方法宣告。在這個方法裡面,我們將會需要進行抽象介面與具體實作類別的對應定義;在這裡,我們需要加入 Autofac 命名空間的參考。在 ConfigureContainer 這個方法內,我們看到了他會使用 ContainerBuilder.RegisterModel 這個方法,所以,我們將會需要自己建立的繼承 Autofac.Module 類別的衍生類別 AutofacModule 類別出來。
C Sharp / C#
public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterModule(new AutofacModule());
}
在這裡,我們需要建立一個 AutofacModule 類別,用來定義抽象型別與具體實作類別的對應關係。不過,由於這個不過,由於這個類別需要繼承 Autofac.Module 這個類別,因此,我們需要在底下的程式碼中,加入 Autofac 的命名參考空間。在這裡,我們將會宣告了,當要註冊 IMessage 這個抽象介面的時候,Autofac DI Container 將會幫我們產生一個 ConsoleMessage 類別的物件。
C Sharp / C#
public class AutofacModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<ConsoleMessage>().As<IMessage>();
    }
}
為了要方便我們進行測試在 ASP.NET Core 專案內,可以使用 Autofac 相依性注入容器之功能,我們建立了底下測試用的抽象介面與兩個有實作這個介面的類別。
C Sharp / C#
public interface IMessage
{
    void Send(string message);
}

public class ConsoleMessage : IMessage
{
    public void Send(string message)
    {
        Console.WriteLine($"ConsoleMessage :{message}");
    }
}
public class FileMessage : IMessage
{
    public void Send(string message)
    {
        Console.WriteLine($"FileMessage :{message}");
    }
}
我們要來在 Controller 內,建立這個控制器的建構函式,所以,請打開 [HomeController.cs] 這個節點檔案,在這裡,我們宣告一個 IMessage 介面型別的欄位 _Message,並且建立該控制器的建構函式,我們將在該建構式內,加入 IMessage 型別參數,確認 ASP.NET Core 專案,可以透過 Autofac DI Container,提供 HomeController 控制器的建構式注入能力,所以,我們將會在該建構式內,將 DI Container 注入進來的 IMessage 參數,設定給該控制器類別的欄位 _Message。
現在,我們可以在 HomeController 類別內來使用 IMessage 的各項功能了,所以,我們在 Index 動作方法內,執行了 _Message.Send("Vulcan Lee") 這個敘述,接下來,我們執行這個專案,看看是否有任何內容輸出到命令字元視窗內。
當我們執行該 ASP.NET Core 專案後,我們在命令提示字元視窗中 (下圖) ,看到了 ConsoleMessage 類別的輸出內容。
Autofac DI Container Constructor Injection
C Sharp / C#
public class HomeController : Controller
{
    IMessage _Message;
    public HomeController(IMessage message)
    {
        _Message = message;
    }
    public IActionResult Index()
    {
        _Message.Send("Vulcan Lee");
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";

        return View();
    }

    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}
我們要來在 Controller 內,建立這個控制器的建構函式,所以,請打開 [HomeController.cs] 這個節點檔案,在這裡,我們宣告一個 IMessage 介面型別的欄位 _Message,並且建立該控制器的建構函式,我們將在該建構式內,加入 IMessage 型別參數,確認 ASP.NET Core 專案,可以透過 Autofac DI Container,提供 HomeController 控制器的建構式注入能力,所以,我們將會在該建構式內,將 DI Container 注入進來的 IMessage 參數,設定給該控制器類別的欄位 _Message。
現在,我們可以在 HomeController 類別內來使用 IMessage 的各項功能了,所以,我們在 Index 動作方法內,執行了 _Message.Send("Vulcan Lee") 這個敘述,接下來,我們執行這個專案,看看是否有任何內容輸出到命令字元視窗內。
當我們執行該 ASP.NET Core 專案後,我們在命令提示字元視窗中 (下圖) ,看到了 ConsoleMessage 類別的輸出內容。
Autofac DI Container Constructor Injection

關於 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 課程



在 ASP.NET Core 專案內使用 Unity 相依性注入 DI 容器

在 ASP.NET Core 專案內使用 Unity 相依性注入 DI 容器

若使要在 ASP.NET Core 專案開發環境,將會使用 ASP.NET Core 內建的相依性注入容器功能用來在類別與其相依性之間達成控制權反轉 (IoC),不過,若您想要使用 Unity DI Container 相依性注入容器來進行取代 ,也就是我們想要在開發 ASP.NET Core 專案的時候,能夠使用 Unity 相依性注入容器來進行開發設計,首先,您需要安裝這個 Unity.Microsoft.DependencyInjection 套件( 因為,這個套件已經整合了 ASP.NET Core 的 Microsoft.Extensions.DependencyInjection 功能 ) 到您的 ASP.NET Core 專案內。
ASP.NET Core Unity Nuget Package Install
ASP.NET Core Unity Nuget Package Preview
接下來,我們需要打開 [Program.cs] 檔案節點,在 WebHost 之後,加入這個方法呼叫 .UseUnityServiceProvider(),如底下程式碼所示;不過,您還需要加入 [Unity.Microsoft.Depende] 這個命名空間,以便可以使用 [UseUnityServiceProvider] 這個方法。
C Sharp / C#
public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseUnityServiceProvider()
            .UseStartup<Startup>();
}
現在,我們需要打開 [Startup.cs] 這個檔案,在這個 Startup 類別內,加入底下這段方法宣告。在這個方法裡面,我們將會需要進行抽象介面與具體實作類別的對應定義;在這裡,我們需要加入 Unity 命名空間的參考。
C Sharp / C#
public void ConfigureContainer(IUnityContainer container)
{
    // Could be used to register more types
    container.RegisterType<IMessage, ConsoleMessage>();
}
為了要方便我們進行測試在 ASP.NET Core 專案內,可以使用 Unity 相依性注入容器之功能,我們建立了底下測試用的抽象介面與兩個有實作這個介面的類別。
C Sharp / C#
public interface IMessage
{
    void Send(string message);
}

public class ConsoleMessage : IMessage
{
    public void Send(string message)
    {
        Console.WriteLine($"ConsoleMessage :{message}");
    }
}
public class FileMessage : IMessage
{
    public void Send(string message)
    {
        Console.WriteLine($"FileMessage :{message}");
    }
}
我們要來在 Controller 內,建立這個控制器的建構函式,所以,請打開 [HomeController.cs] 這個節點檔案,在這裡,我們宣告一個 IMessage 介面型別的欄位 _Message,並且建立該控制器的建構函式,我們將在該建構式內,加入 IMessage 型別參數,確認 ASP.NET Core 專案,可以透過 Unity DI Container,提供 HomeController 控制器的建構式注入能力,所以,我們將會在該建構式內,將 DI Container 注入進來的 IMessage 參數,設定給該控制器類別的欄位 _Message。
現在,我們可以在 HomeController 類別內來使用 IMessage 的各項功能了,所以,我們在 Index 動作方法內,執行了 _Message.Send("Vulcan Lee") 這個敘述,接下來,我們執行這個專案,看看是否有任何內容輸出到命令字元視窗內。
當我們執行該 ASP.NET Core 專案後,我們在命令提示字元視窗中 (下圖) ,看到了 ConsoleMessage 類別的輸出內容。
Unity DI Container Constructor Injection
C Sharp / C#
public class HomeController : Controller
{
    IMessage _Message;
    public HomeController(IMessage message)
    {
        _Message = message;
    }
    public IActionResult Index()
    {
        _Message.Send("Vulcan Lee");
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";

        return View();
    }

    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

關於 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 課程