非平凡的WinForm应用程序中的依赖注入

时间:2015-07-17 14:50:06

标签: dependency-injection

我想问一下可以帮助将依赖注入引入样本WinForm应用程序的人。 我们有一个具有以下结构的应用程序(不是完整的图表):

MainForm <-> MainModel
| |└ -----------------------┐
| └ ------------┐           |
FA <-> MA    FB <-> MB    FC <-> MC
| |                       |└-----------------┐       
| └-----------┐           └----┐             |
FAA <-> MAA   FAB <-> MAB      FCA <-> MCA  FCB <-> MCB
                               |||
                ┌--------------┘|└----------------┐
               FCAA <-> MCAA   FCAB <-> MCAB   FCAC <-> MCAC
               ||
┌--------------┘└----------------┐
FCAAA <-> MCAAA                 FAB <-> MAB

我可以实现组合根,我可以输入这样的内容:

var container = new Container();
container.RegisterSingle<IMainForm, MainForm>();
container.Register<IMainModel, MainModel>();
container.Register<IFA, FA>();

...

我知道如何获得第一个MainForm并显示它(简单的resovling)。但我仍在努力解决如何根据需要创建其他表单和模型的正确逻辑。我不想将我的容器的引用传递给mainform并解决mainform中的依赖关系,因为它闻起来像servicelocator模式。我想避免使用CreateFA,CreateFB,CreateFAAA等方法创建模糊的Factory ...我想避免将完整的构造图传递给mainform。

此外我想在MCAA中使用一些接口IJob的实现,它可以在组合根目录中定义,但我想避免通过所有级别的表单或传递某种工厂来传递IJob的实例...

如何创建窗口和模型等所有实例的最简单方法。因为我需要他们使用ServiceLocator ......但是,那么...... DI怎么样?

首选DI:SimpleInjector,首选语言:C#

2 个答案:

答案 0 :(得分:1)

我认为你基本上有3种选择吗?虽然你已经决定你不喜欢其中的两个:)

  • 从组合根
  • 将表单实例注入MainForm
  • 在合成根
  • 中注入单个工厂以将所有表单创建到MainForm中
  • 注入许多工厂,将每个Form单独创建到组合根目录中的MainForm中。

我更喜欢第二个选项到第二个选项,因为每个表单只需要工厂用于实际需要创建的表单。

第一个选项的可行性取决于您的表单是否为单个实例。

DI和容器并不会神奇地为您提供解决方案,它们只是简化了您首选解决方案的布线。

答案 1 :(得分:1)

  

我想避免将完整的构造图传递给mainform。

如果您设计您的应用程序为composed entirely up-front,那么这会让您的生活更轻松。

如果您的担忧与效果有关,请先预先编写整个图表,然后衡量,看看是否存在性能问题。如果您发现自己有需要延迟的子图表,请you can use the Virtual Proxy pattern to defer creation of branches直到需要它们为止。

如果真正担心的是无法预先创建整个图形,因为某些子图形依赖于运行时值,您可以use an Abstract Factory;您不必提供无数的Abstract Factory接口:单个通用接口IFactory<T, TInput>就足够了。

基于运行时值选择依赖关系的其他替代方法是

  

此外,我想在MCAA中使用IJob接口的一些实现

只需将IJob注入MCAA就像任何其他类一样。如果这些图层永远不会创建MCAA,则不必将其传递给图层。只有组合根需要保存对实现的引用,因为只有组合根创建MCAA