我有一个Windows窗体。它包含许多控制器:网格,按钮,甚至是TreeView
。事件是在其中的大多数上定义的。例如,有多个独立的事件以独立的方式查询或命令我的SQL Server。对于几乎所有的情况,接口分离原则都迫使我不合并这些接口。
因为我正在进行依赖项注入,所以Windows窗体的构造函数被大量过度注入。我在窗体的构造函数中有四个参数,用于一个网格。示例包括:网格的初始填充、查询一个单元格中组合框的值列表、当一个其他类型改变时重新填充某些类型的单元格等。我估计用不了多久,我的构造函数就会有一些荒谬的东西,比如20个参数,所有的接口都查询服务器。
在Windows窗体中可以避免这种情况吗?我猜想,如果我能以某种方式构建每个组件,然后将它们提供给我的构造函数,而不是让我的表单知道每个组件的依赖关系,我会更好。也就是说,我想我宁愿换掉
MyForm(IQueryGridTimes TimeQueryRepo, ICommandGridTimeCells TimeCommandRepo, IQueryTheWholeGrid GridInitialPopulator, ..., IQueryForTheTreeView TreeViewPopulator)
字符串
与
var grid = new WhateverGrid(IQueryGridTimes TimeQueryRepo, ICommandGridTimeCells TimeCommandRepo, IQueryTheWholeGrid GridInitialPopulator)
var tress = new WhateverTreeview(QueryForTheTreeView TreeViewPopulator)
MyForm(grid, ..., trees,)
型
这是明智和可能的吗?我对其他方法持开放态度,不需要假设任何依赖注入容器(我宁愿不使用任何)。
2条答案
按热度按时间eulz3vhy1#
Mark Seemann在他的blog中描述了一些处理构造函数过度注入的可能方法:
Seemann还指出,可能有一些有效的情况,让构造函数具有大量的依赖项,这只是最可维护的解决方案,或者真的不是问题。
Steven还建议使用Mediator-like patterns作为替代解决方案,详见他的blog post。有一些库可以帮助实现这种模式,比如MediatR(使用反射)和Mediator(使用源代码生成器)。但是,这将增加间接性,并使跟踪表单正在使用哪些依赖项变得更加困难。因此,单元测试可能会变得更加脆弱,您需要验证自己是否注册了所有必需的处理程序。
注意switching to Property Injection does not reduce the number of dependencies, but only implies they are optional instead of mandatory。
63lcw9qa2#
有许多不同的方法来实现类似于你想要的东西。
最小化依赖项数量的一个快速方法是聚合其中的一些。四个或更多的依赖项只填充一个网格似乎太多了。相反,您可以拥有某种类型的存储库依赖关系,它公开来自缓存或永久存储的所有必要数据。一个接口可以包含多个函数。
或者,您也可以不使用建构函式。大多数DI框架都不按惯例使用它们,但仅此而已。您可以轻松地编写一个注入到属性中的DI框架,然后只需为引擎提供要填充的属性。
作为对前面建议的跟进,编写一个源生成器来处理DI对象的创建是相对简单的,而不需要求助于反射。当你一开始只有几十个对象时,反射并不是那么糟糕,但是source genning它们肯定更好。