C# 在具有子窗体的WinForms应用程序中正确执行依赖项注入

C# 在具有子窗体的WinForms应用程序中正确执行依赖项注入,c#,winforms,dependency-injection,C#,Winforms,Dependency Injection,假设主窗体有几个菜单项。每个菜单项将显示另一个窗体。在这种情况下,下面的代码是执行依赖项注入的好方法吗 public class MainForm: Form { private IAboutForm _aboutForm; private IOptionsForm _optionsForm; private IDownloadsForm _downloadsForm; MainForm(IAboutForm aboutForm, IOptionsForm optionsFor

假设主窗体有几个菜单项。每个菜单项将显示另一个窗体。在这种情况下,下面的代码是执行依赖项注入的好方法吗

public class MainForm: Form {
  private IAboutForm _aboutForm;
  private IOptionsForm _optionsForm;
  private IDownloadsForm _downloadsForm;

  MainForm(IAboutForm aboutForm, IOptionsForm optionsForm, IDownloadsForm downloadsForm) { // add as many form dependencies as required
    _aboutForm = aboutForm;
    _optionsForm = optionsForm;
    _downloadsForm = downloadsForm;

    InitializeComponent();
  }

  private void AboutMenuItem_Click(object sender, System.EventArgs e) {
    _aboutForm.ShowDialog(this);
  }

  private void DownloadsMenuItem_Click(object sender, System.EventArgs e) {
    _downloads.Show();
    _downloads.BringToFront();
  }

}

这可以正常工作,但是扩展不好——如果您继续添加表单,一段时间后您的构造函数将变得巨大。如果你再也不加了,那么你可能就没事了。如果您知道您将添加更多,或者不认为您将添加更多,但最终会这样做,那么您可能希望注入某种形式的IFormFactory,如下所示:

IFormsFactory formsFactory;
MainForm(IFormsFactory formsFactory)
{
    _formsFactory = formsFactory;
}
然后,您可以根据需要创建依赖表单:

private void AboutMenuItem_Click(object sender, System.EventArgs e) {
    IAboutForm aboutForm = _formsFactory.CreateAboutForm();
    aboutForm.ShowDialog(this);
}
有几种方法可以做到这一点。您可以将所有表单保留为成员变量,只需使用注入的工厂在构造函数中创建它们。如果性能是一个问题,并且在程序的生命周期中,每个实例只需要一个实例,那么这是很好的

请注意,如果需要,也可以将“构造”参数添加到
factory.CreateXXX()
调用中

在工厂内部,它将知道如何创建每个表单。如果使用IoC容器,甚至不需要创建IFactory接口的具体内容。但是,如果创建表单有特殊的逻辑,那么您可能希望创建一个混凝土,并将注入的IFactory解析为该混凝土

关于这一点,还有很多可以说的,但我认为这是一个很好的起点。希望能有帮助