如何在 Winforms C# 中定義依賴注入?
介面IC類別:
public interface ICategory
{
void Save();
}
類 CategoryRepository:
public class CategoryRepository : ICategory
{
private readonly ApplicationDbContext _context;
public CategoryRepository(ApplicationDbContext contex)
{
_context = contex;
}
public void Save()
{
_context.SaveChanges();
}
}
表格1:
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();
}
}
表格2:
public partial class Form2 : Form
{
private readonly ICategury _ic;
public Form2(ICategury ic)
{
InitializeComponent();
_ic=ic
}
}
問題?
Program.cs中依賴注入的定義
Application.Run(new Form1());Form 2呼叫時依賴注入的定義
Form2 frm= new Form2(); frm.show();
uj5u.com熱心網友回復:
要在 WinForms .NET 5 或 6 中使用 DI,您可以執行以下步驟:
創建 WinForms .NET 應用程式
安裝 Microsoft.Extensions.Hosting 包(它為您提供了一系列有用的功能,如 DI、日志記錄、配置等)
添加一個新界面,
IHelloService.cs:public interface IHelloService { string SayHello(); }為您的服務添加一個新的實作
HelloService.cs:public class HelloService : IHelloService { public string SayHello() { return "Hello, world!"; } }修改
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>(); }); } }
現在,你可以注入IHelloService中Form1并使用它:
//using Microsoft.Extensions.DependencyInjection;
public partial class Form1 : Form
{
private readonly IHelloService helloService;
public Form1(IHelloService helloService, Form2 form2)
{
InitializeComponent();
this.helloService = helloService;
MessageBox.Show(helloService.SayHello());
}
}
如果要Form2使用DI展示,首先需要注冊它 services.AddTransient<Form2>();,然后根據Form2的使用情況,可以使用以下選項之一:
如果您
Form2在 的整個生命周期中只需要一個 的實體Form1,那么您可以將其作為依賴項注入 的建構式Form1并存盤該實體并在需要時顯示它。但請注意:它只會初始化一次,打開
Form1時不會再次初始化。您也不應該處理它,因為它是傳遞給Form1.public Form1(IHelloService helloService, Form2 form2) { InitializeComponent(); form2.ShowDialog(); }如果你需要多個實體
Form2或者你需要多次初始化它,那么你可能會得到一個這樣的實體:using (var form2 = Program.ServiceProvider.GetRequiredService<Form2>()) form2.ShowDialog();
uj5u.com熱心網友回復:
在 winforms 中,表單的建構式應該是默認建構式。您應該將要在建構式中傳遞的值設定為屬性。在表單加載期間,您可以檢查該屬性是否已設定,如果未按預期執行:使用默認值,或警告操作員,或關閉表單。
當然,至少有一個表單應該決定應該注入哪個 ICategory。例如主要形式:
public class MainForm
{
private ICategory Category {get; }
public MainForm()
{
InitializeComponent();
CategoryFactory factory = new CategoryFactory();
this.Category = factory.Create();
}
稍后,MainForm 必須顯示 Form1,例如在單擊按鈕后:
private void ShowForm1()
{
using (Form1 form = new Form1())
{
form.Category = this.Category;
var dlgResult = form.ShowDialog(this);
if (dlgResult == DialogResult.Ok)
{
this.ProcessDialogResult(...);
}
}
}
表格1:
class Form1 : ...
{
public Form1()
{
InitializeComponent(); // subscribe to event form load
}
public ICategory Category {get; }
public void FormLoading(object sender, ...)
{
// check if Category set, and report problems
if (this.Category == null)
{
this.LogMissingCategory();
this.WarnOperatorMissingCategory();
this.Close();
}
...
}
private void ShowForm2()
{
using (Form2 form = new Form2())
{
form.Category = this.Category;
var dlgResult = form.ShowDialog(this);
if (dlgResult == DialogResult.Ok)
{
...
}
}
}
}
如果您有很多需要 Category 的表單,那么顯然有類似 CategoryForm 的東西:
class CategoryForm : Form
{
public ICategory Category {get; }
protected override void OnFormLoading(...)
{
// TODO check Category
base.OnFormLoading(...);
}
}
classs Form3 : CategoryForm {...}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/392550.html
