這是我在ExpressionOfNeeds后面的代碼
private readonly IExpressionOfNeeds _expressionOfNeeds;
public FrmExpressionOfNeeds(IExpressionOfNeeds expressionOfNeeds)
{
InitializeComponent();
_expressionOfNeeds = expressionOfNeeds;
}
private async void FrmExpressionOfNeeds_Load(object sender, EventArgs e)
{
GCData.DataSource = await _expressionOfNeeds.GetAllExpressionOfNeeds();
}
這是我在MainForm后面的代碼
private readonly IExpressionOfNeeds _expressionOfNeeds;
private readonly IService2 _service2;
private readonly IService3 _service3;
//and so on and so forth
public XtraMain()
{
InitializeComponent();
}
private void bbtnExpressionOfNeeds_ItemClick(object sender, ItemClickEventArgs e)
{
FrmExpressionOfNeeds frme = new(_expressionOfNeeds)
{
Name = "FrmExpressionOfNeeds"
};
ViewChildForm(frme);
}
private void bbtnForm2_ItemClick(object sender, ItemClickEventArgs e)
{
Form2 frme = new(_service2)
{
Name = "Form2"
};
ViewChildForm(frme);
}
private void bbtnForm3_ItemClick(object sender, ItemClickEventArgs e)
{
Form3 frme = new(_service3)
{
Name = "Form3"
};
ViewChildForm(frme);
}
依此類推
,這是我在Program類后面的代碼
static void Main()
{
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddScoped<XtraMain>();
services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
services.AddSingleton<IExpressionOfNeeds, ExpressionOfNeeds>();
});
var host = builder.Build();
using (var serviceScope = host.Services.CreateScope())
{
var services = serviceScope.ServiceProvider;
var mainform = services.GetRequiredService<XtraMain>();
Application.Run(mainform);
}
}
問題是_expressionOfNeeds 的值始終為null,我找不到初始化它的方法
更新
我有很多表單和很多介面
我只將它限制在一個示例中,因此代碼不會太大。
uj5u.com熱心網友回復:
你快到了。您已將表單和服務注冊到 DI 容器中,但忘記將介面注入表單的建構式。
您必須將依賴介面添加到表單的建構式(首選解決方案),或者稍后在需要時從服務提供者獲取它們的實體。
您可以在以下帖子中找到分步示例:
- 如何在 WinForms 中使用依賴注入。
假設你有MainForm一個依賴于 的IMyServie,那么你應該有一個這樣的建構式:
IMyService _myService;
public MainForm(IMyService myService)
{
_myService = myService;
}
然后,一旦您注冊MainForm并IMyService進入 DI 容器并從服務提供商處獲取實體,一切都會按預期作業。這是主要入口點:
static class Program
{
public static IServiceProvider ServiceProvider { get; private set; }
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
var host = CreateHostBuilder().Build();
ServiceProvider = host.Services;
Application.Run(ServiceProvider.GetRequiredService<MainForm>());
}
static IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureServices((context, services)=>{
services.AddTransient<IMyService, MyService>();
services.AddTransient<MainForm>();
});
}
}
如果由于某種原因(就像我在鏈接答案中解釋的那樣)您需要獲取服務實體而不將其注入建構式中,那么您可以使用Program.ServiceProvider.GetRequiredService<SomeFormOrService>().
uj5u.com熱心網友回復:
我建議創建一個工廠來獲取主表單所需的表單
public interface IFormFactory {
TForm Create<TForm>() where TForm : Form;
}
假設在這種情況下要創建的型別都來自Form
實作將使用服務提供者來決議提供的表單型別
public class FormFactory: IFormFactory {
private readonly IServiceProvider services;
public FormFactory(IServiceProvider services) {
this.services = services;
}
public TForm Create<TForm>() where TForm : Form {
return services.GetRequiredService<TForm>();
}
}
主表單將需要依賴于工廠,以便它可以根據需要創建表單
//...
private readonly IFormFactory factory;
public XtraMain(IFormFactory factory) {
InitializeComponent();
this.factory = factory;
}
private void bbtnExpressionOfNeeds_ItemClick(object sender, ItemClickEventArgs e) {
FrmExpressionOfNeeds frme = factory.Create<FrmExpressionOfNeeds>();
frme.Name = "FrmExpressionOfNeeds";
ViewChildForm(frme);
}
private void bbtnForm2_ItemClick(object sender, ItemClickEventArgs e) {
Form2 frme = factory.Create<Form2>();
frme.Name = "Form2";
ViewChildForm(frme);
}
private void bbtnForm3_ItemClick(object sender, ItemClickEventArgs e) {
Form3 frme = factory.Create<Form3>();
frme.Name = "Form3";
ViewChildForm(frme);
}
//...
確保服務提供商解決的所有問題在啟動時都已注冊
static void Main() {
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) => {
services.AddScoped<XtraMain>();
services.AddTransient<FrmExpressionOfNeeds>();
services.AddTransient<Form2>();
services.AddTransient<Form3>();
services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
services.AddSingleton<IExpressionOfNeeds, ExpressionOfNeeds>();
services.AddSingleton<IFormFactory, FormFactory>();
});
var host = builder.Build();
using (var serviceScope = host.Services.CreateScope()) {
IServiceProvider services = serviceScope.ServiceProvider;
XtraMain mainform = services.GetRequiredService<XtraMain>();
Application.Run(mainform);
}
}
這樣,無論有多少表單和介面,容器都可以決議和注入所有依賴項。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/433989.html
