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
,在后续的代码优化过程中可对此予以关注并修正。