3

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

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();
  }

}
4

1 回答 1

9

这可以正常工作,但不能很好地扩展 - 如果您继续添加表单,您的构造函数将在一段时间后变得巨大。如果你不再添加,那么你可能没问题。如果你知道你会添加更多,或者认为你不会但最终会这样做,你可能想要注入某种 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 解析为该具体。

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

于 2013-05-10T19:27:24.033 回答