'How to use dependency injection in WinForms
How to define dependency injection in Winforms C#?
Interface ICategory:
public interface ICategory
{
void Save();
}
Class CategoryRepository:
public class CategoryRepository : ICategory
{
private readonly ApplicationDbContext _context;
public CategoryRepository(ApplicationDbContext contex)
{
_context = contex;
}
public void Save()
{
_context.SaveChanges();
}
}
Form1:
public partial class Form1 : Form
{
private readonly ICategury _ic;
public Form1(ICategury ic)
{
InitializeComponent();
_ic=ic
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm= new Form2();
frm.show();
}
}
Form2:
public partial class Form2 : Form
{
private readonly ICategury _ic;
public Form2(ICategury ic)
{
InitializeComponent();
_ic=ic
}
}
Problem?
Definition of dependency injection in Program.cs
Application.Run(new Form1());Definition of dependency injection at the time of Form 2 call
Form2 frm= new Form2(); frm.show();
Solution 1:[1]
How to use Dependency Injection (DI) in Windows Forms (WinForms)
To use DI in a WinForms .NET 5 or 6 you can do the following steps:
Create a WinForms .NET Application
Install Microsoft.Extensions.Hosting package (which gives you a bunch of useful features like DI, Logging, Configurations, and etc.)
Add a new interface,
IHelloService.cs:public interface IHelloService { string SayHello(); }Add a new implementation for your service
HelloService.cs:public class HelloService : IHelloService { public string SayHello() { return "Hello, world!"; } }Modify the
Program.cs://using Microsoft.Extensions.DependencyInjection; static class Program { [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var host = CreateHostBuilder().Build(); ServiceProvider = host.Services; Application.Run(ServiceProvider.GetRequiredService<Form1>()); } public static IServiceProvider ServiceProvider { get; private set; } static IHostBuilder CreateHostBuilder() { return Host.CreateDefaultBuilder() .ConfigureServices((context, services)=>{ services.AddTransient<IHelloService, HelloService>(); services.AddTransient<Form1>(); }); } }
Now you can inject IHelloService in Form1 and use it:
//using Microsoft.Extensions.DependencyInjection;
public partial class Form1 : Form
{
private readonly IHelloService helloService;
public Form1(IHelloService helloService)
{
InitializeComponent();
this.helloService = helloService;
MessageBox.Show(helloService.SayHello());
}
}
If you want to show Form2 using DI, you first need to register it services.AddTransient<Form2>();, then depending to the usage of Form2, you can use either of the following options:
If you only need a single instance of
Form2in the whole life time ofForm1, then you can inject it as a dependency to the constructor ofForm1and store the instance and show it whenever you want.But please pay attention: it will be initialized just once, when you open
Form1and it will not be initialized again. You also should not dispose it, because it's the only instance passed toForm1.public Form1(IHelloService helloService, Form2 form2) { InitializeComponent(); form2.ShowDialog(); }If you need multiple instances of
Form2or you need to initialize it multiple times, then you may get an instance of it like this:using (var form2 = Program.ServiceProvider.GetRequiredService<Form2>()) form2.ShowDialog();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
