WinForm依賴注入簡單使用

阿遇而已發表於2024-11-19

Program.cs

using Microsoft.Extensions.DependencyInjection;
using WinFormsApp1.Helper;

namespace WinFormsApp1;

internal static class Program
{
    // 服務容器,用於儲存和提供已註冊的服務
    public static IServiceProvider ServiceProvider { get; set; }

    [STAThread]
    static void Main()
    {
        // 初始化應用程式配置
        ApplicationConfiguration.Initialize();

        // 配置服務容器
        var serviceCollection = new ServiceCollection().InJection();

        // 構建服務提供者
        ServiceProvider = serviceCollection.BuildServiceProvider();

        // 從服務提供者中獲取指定鍵對應的Form型別服務
        var form = ServiceProvider.GetKeyedService<Form>(nameof(PictureBoxTest));

        // 啟動應用程式並傳入獲取到的Form例項,使應用程式開始執行並展示相應介面
        Application.Run(form);
    }
}

DIHelper.cs

using Microsoft.Extensions.DependencyInjection;

namespace WinFormsApp1.Helper;

public static class DIHelper
{
    // 擴充套件方法,用於向IServiceCollection中註冊特定的Form服務
    public static IServiceCollection InJection(this IServiceCollection service)
    {
        // 以nameof(BaseControlTest)為鍵,註冊BaseControlTest型別的Form為單例服務
        service.AddKeyedSingleton<Form, BaseControlTest>(nameof(BaseControlTest));

        // 以nameof(PictureBoxTest)為鍵,註冊PictureBoxTest型別的Form為單例服務
        service.AddKeyedSingleton<Form, PictureBoxTest>(nameof(PictureBoxTest));

        return service;
    }
}

以下是關於本程式碼中所運用的依賴注入方法的詳細闡述:

一、整體流程概述

Program.cs檔案的Main方法中,整個依賴注入及應用程式啟動的流程如下:

首先,執行ApplicationConfiguration.Initialize();語句,以此完成應用程式配置的初始化操作,這一步驟為後續的程式執行奠定了基礎配置環境。

隨後,建立一個ServiceCollection的例項,並呼叫自定義的擴充套件方法InJection對其進行服務容器的配置操作。透過該擴充套件方法,能夠向服務容器中註冊所需的各類服務。

在完成服務容器的配置後,利用已配置好的ServiceCollection例項構建出IServiceProvider,此即為服務提供者。它扮演著在應用程式執行過程中提供已註冊服務的關鍵角色。

最後,透過ServiceProvider.GetKeyedService<Form>(nameof(PictureBoxTest));語句,依據特定的鍵(在此為nameof(PictureBoxTest))從服務提供者中獲取對應的Form型別服務例項。接著,將獲取到的該Form例項傳遞給Application.Run方法,從而啟動應用程式的訊息迴圈,使應用程式得以正常執行並展示出相應的介面。

二、服務序號產生器制

DIHelper.cs檔案中,定義了DIHelper靜態類,其中包含了用於服務註冊的擴充套件方法InJection

該擴充套件方法主要針對IServiceCollection型別進行擴充套件,其接收一個IServiceCollection例項作為引數(此引數在Program.csMain方法中進行建立並傳入)。

InJection擴充套件方法內部,藉助AddKeyedSingleton方法實現了兩種不同型別的Form服務註冊操作:

其一,以nameof(BaseControlTest)作為鍵,將BaseControlTest型別的Form註冊為單例服務。這意味著在整個應用程式的生命週期內,只會存在一個該型別的Form例項,並且該例項將在需要時由服務提供者統一提供。

其二,以nameof(PictureBoxTest)為鍵,把PictureBoxTest型別的Form同樣註冊為單例服務。其原理與上述類似,確保在應用程式執行過程中,對於該型別Form服務的獲取始終指向同一個例項。

三、服務獲取與應用

回到Program.csMain方法中,當成功構建服務提供者ServiceProvider之後:

透過ServiceProvider.GetKeyedService<Form>(nameof(PictureBoxTest));這一語句,依據nameof(PictureBoxTest)這個特定的鍵,從服務提供者中準確獲取到對應的Form型別服務例項。此處所獲取到的例項,實際上就是之前在服務註冊階段以nameof(PictureBoxTest)為鍵所註冊的PictureBoxTest型別的Form服務例項(前提是假設PictureBoxTest是一個繼承自Form的具體型別)。

最終,將獲取到的Form例項傳遞給Application.Run方法,以此啟動應用程式並使其能夠利用所注入的服務來完成相關的功能。具體的功能實現則取決於PictureBoxTest等各類表單類內部的具體邏輯設計。

值得一提的是,在程式碼中可能存在一處細微的瑕疵,即InJection方法名或許應當為Injection,在後續的程式碼最佳化過程中可對此予以關注並修正。

相關文章