Ami*_*ati 10 c# dependency-injection winforms
我在 DI 方面的知识非常有限。我正在一个解决方案中开发一个 WinForm 项目,该解决方案中的所有其他地方都使用了Microsoft 扩展依赖注入。
我需要将一些依赖项传递给 MainForm 的构造函数:
public partial class MainForm : Form
{
public MainForm(ISomeThing someThing)
{
}
}
Run Code Online (Sandbox Code Playgroud)
在 Main 方法中,将 MainForm 的一个实例传递给 Run 方法:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用 DI 通过服务提供者实例化 Mainform 的一个实例:
private static IServiceProvider ServiceProvider { get; set; }
Run Code Online (Sandbox Code Playgroud)
然后为它分配一个对象,如下所示:
static void ConfigureServices()
{
var services = new ServiceCollection();
services.AddTransient<ISomeThing, SomeThing>();
ServiceProvider = services.BuildServiceProvider();
}
Run Code Online (Sandbox Code Playgroud)
然后调用ConfigureServices()中Main(),如下所示:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ConfigureServices();
Application.Run(ServiceProvider.GetService(MainForm));
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到一个编译错误:“ MainForm 是一种类型,在给定的上下文中无效”
我发现以下链接使用SimpleInjector或Unity使用类似方法, 但我不知道如何将其与这种 DI 一起使用?或者我必须使用其他DI?
谢谢
您正在尝试获取与System.Type该类对应的实例。
这就是typeof()关键字的作用:
GetService(typeof(MainForm))
Run Code Online (Sandbox Code Playgroud)
请注意,您还需要将结果转换为Form.
我会修改它如下..
您不需要使用参数将任何内容传递给 MainForm 的构造函数。
在 Program 类中,Something 的一个实例被注册为 ISomething 的实现者,但 Application.Run() 保持不变,
using Microsoft.Extensions.DependencyInjection; // provides DI
using SomeThing; // implements ISomeThing interface and SomeThing class
/*Program.cs */
public static class Program
{
//..
public static IServiceProvider ServiceProvider { get; set; }
static void ConfigureServices()
{
var services = new ServiceCollection();
services.AddTransient<ISomeThing, SomeThing>();
ServiceProvider = services.BuildServiceProvider();
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ConfigureServices();
Application.Run(new MainForm());
}
}
Run Code Online (Sandbox Code Playgroud)
现在在 MainForm 中,构造函数将查询注册的依赖项并将其保存为私有属性,例如
public class MainForm: Form
{
// ..
private readonly IMySomeThing _mySomething;
public MainForm()
{
_mySomething = (IMySomeThing)Program.ServiceProvider.GetService(typeof(IMySomeThing));
}
}
Run Code Online (Sandbox Code Playgroud)
在 MainForm ctor 完成后,可以从 MainForm 的任何地方访问私有字段 _mySomething(或其方法可以调用)。哪个类实现 IMySomething 由 ServiceProvider 的注册控制。这允许通过替换某些拥有的类来更改类的行为。
我使用 DI 来简化某些单元测试。例如,在单元测试中,实现一些复杂子任务的依赖项可以用简单的真/假返回替代来代替。这种测试方法通常被称为“模拟”。它允许对中级和高级程序进行单元测试。
我在代码中添加了一个辅助函数,以使其更具可读性:
public static T? GetService<T>() where T : class
{
return (T?)ServiceProvider.GetService(typeof(T));
}
Run Code Online (Sandbox Code Playgroud)
//was:
// thing = (iThing)Program.ServiceProvider.GetService(typeof(iThing));
//now:
thing = Program.GetService<iThing>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12051 次 |
| 最近记录: |