來,winform使用依賴注入!

來,winform使用依賴注入!

關於依賴注入是什麼?依賴注入是一種具體的編碼技巧,對我來說最明顯的就是解決代碼的耦合性。

最后更新 2022/4/22 上午7:21
AZRNG 鹏祥
预计阅读 4 分钟
分类
Winform
标签
.NET Winform 依賴注入 IOC

站長:winform 的分享文章不多,這個技術相對來說已經十分穩定了,該有的都有了,今天分享其他號寫的 winform 依賴注入一文,希望做相關開發的朋友能有新的體會。

1. 居間

關於依賴注入是什麼?依賴注入是一種具體的編碼技巧,對我來說最明顯的就是解決代碼的耦合性。

2. 目的

asp.net core 中本身容器容器已經創建好了,只需要往容器添加服務即可,但是在 winform 中默認還是通過 new 的方式來進行操作的(雖然我已經升級成了.net6),最近在把一個開源項目進行增加自用的功能,然後我順帶將原來的 netf 升級為 netcore,然後就想用依賴注入方式去試試了。

c/s 代碼寫的少,如有不對,麻煩指正。

3. 操作

本文示例環境:vs2022、.net6、windows 窗體應用

4. 準備

示例包含以下代碼

  • 窗體:form1、form2

  • Service:IUserservice、Userservice、IOrderService、OrderService

public interface IUserservice
{
    string GetName();
}

public class UserService : IUserservice
{
    public string GetName()
    {
        return "IUserservice";
    }
}

public interface IOrderService
{
    string GetName();
}

public class OrderService : IOrderService
{
    public string GetName()
    {
        return "IOrderService";
    }
}

5. 場景

在 form1 通過構造函數注入 iuserservice,並且在 load 事件裡面調用 iuserservice 的獲取名稱方法,點擊頁面按鈕後讓 form2 顯示,form2 中通過依賴注入了 iorderservice 在 load 事件裡面調用 iorderservice 的獲取名稱方法。如果可以多次操作不報錯就是成功。

6. 開始

引用組件

<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />

增加了一個 serviceproviderhelper 的操作類

public static class ServiceProviderHelper
{
    /// <summary>
    /// 全局服务提供者
    /// </summary>
    public static IServiceProvider ServiceProvider { get; private set; } = null!;

    /// <summary>
    /// 初始化构建ServiceProvider对象
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <exception cref="ArgumentNullException"></exception>
    public static void InitServiceProvider(ServiceProvider serviceProvider)
    {
        ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider));

        ServiceProvider = serviceProvider;
    }

    /// <summary>
    /// 获取Form服务
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static Form GetFormService(Type type)
    {
        var service = ServiceProvider.GetRequiredService(type);
        if (service is Form fService)
        {
            return fService;
        }
        else
        {
            throw new ArgumentException($"{type.FullName} is not a Form");
        }
    }

    /// <summary>
    /// 获取Form服务
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static T GetService<T>() where T : class
    {
        return ServiceProvider.GetRequiredService<T>();
    }
}

修改 program 方法

internal static class Program
{
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    private static void Main()
    {
        //.net6写法 之前是三行合一行
        ApplicationConfiguration.Initialize();

        //创建服务容器
        var services = new ServiceCollection();
        //添加服务注册
        ConfigureServices(services);

        //构建ServiceProvider对象
        ServiceProviderHelper.InitServiceProvider(services.BuildServiceProvider());

        //获取指定服务
        var main = ServiceProviderHelper.ServiceProvider.GetRequiredService<Form1>();
        Application.Run(main);
    }

    /// <summary>
    /// 注入服务
    /// </summary>
    /// <param name="services"></param>
    public static void ConfigureServices(IServiceCollection services)
    {
        //批量注入可以使用Scrutor或者自己封装
        services.AddScoped<IUserservice, UserService>();
        services.AddScoped<IOrderService, OrderService>();

        //其他的窗体也可以注入在此处
        services.AddSingleton(typeof(Form1));
        services.AddTransient(typeof(Form2));
    }
}

分別在 form1 和 form2 進行注入

private readonly IUserservice _userservice;

public Form1(IUserservice userservice)
{
    InitializeComponent();
    _userservice = userservice;
}

private readonly IOrderService _orderService;

public Form2(IOrderService orderService) : this()
{
    _orderService = orderService;
}

點擊 form1 窗體按鈕讓 form2 窗體顯示

private void button1_Click(object sender, EventArgs e)
{
    var form2 = ServiceProviderHelper.GetFormService(typeof(Form2));
    form2.Show();
}

正常操作幾次並沒有發現異常。

7. 資料

在.net core3.1 上基於 winform 實現依賴注入實例:http://www.ty2y.com/study/znetcore3.1sjywinformsxylzrsl.html

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2024/2/29

winform中也可以這樣做數據展示

在做winform開發的過程中,經常需要做數據展示的功能,之前一直使用的是gridcontrol控制項,今天想通過一個示例,跟大家居間一下如何在winform blazor hybrid中使用ant design blazor中的table組件做數據展示。

继续阅读
同分类 / 同标签 2024/2/29

winform的界面也可以變好看?

前幾天跟大家居間了在winform中使用blazor hybrid,而且還說配上blazor的ui可以讓我們的winform程式設計的更加好看,接下來我想以一個在winform blazor hybrid中繪圖的例子來進行說明,希望對你有所幫助。

继续阅读