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.cs
的Main
方法中进行创建并传入)。
在InJection
扩展方法内部,借助AddKeyedSingleton
方法实现了两种不同类型的Form
服务注册操作:
其一,以nameof(BaseControlTest)
作为键,将BaseControlTest
类型的Form
注册为单例服务。这意味着在整个应用程序的生命周期内,只会存在一个该类型的Form
实例,并且该实例将在需要时由服务提供者统一提供。
其二,以nameof(PictureBoxTest)
为键,把PictureBoxTest
类型的Form
同样注册为单例服务。其原理与上述类似,确保在应用程序运行过程中,对于该类型Form
服务的获取始终指向同一个实例。
三、服务获取与应用
回到Program.cs
的Main
方法中,当成功构建服务提供者ServiceProvider
之后:
通过ServiceProvider.GetKeyedService<Form>(nameof(PictureBoxTest));
这一语句,依据nameof(PictureBoxTest)
这个特定的键,从服务提供者中准确获取到对应的Form
类型服务实例。此处所获取到的实例,实际上就是之前在服务注册阶段以nameof(PictureBoxTest)
为键所注册的PictureBoxTest
类型的Form
服务实例(前提是假设PictureBoxTest
是一个继承自Form
的具体类型)。
最终,将获取到的Form
实例传递给Application.Run
方法,以此启动应用程序并使其能够利用所注入的服务来完成相关的功能。具体的功能实现则取决于PictureBoxTest
等各类表单类内部的具体逻辑设计。
值得一提的是,在代码中可能存在一处细微的瑕疵,即InJection
方法名或许应当为Injection
,在后续的代码优化过程中可对此予以关注并修正。