我习惯于 Web 应用程序中的 IoC/DI - 主要是 Ninject 和 MVC3。我的控制器是为我创建的,填充了所有的依赖项、子依赖项等。
但是,在胖客户端应用程序中情况有所不同。我必须创建自己的对象,或者我必须恢复到服务定位器风格的方法,在这种方法中我要求内核(可能通过一些接口,以允许可测试性)给我一个完整的对象与依赖关系。
但是,我已经看到有几个地方将 Service Locator 描述为反模式。
所以我的问题是 - 如果我想在我的胖客户端应用程序中从 Ninject 中受益,有没有更好/更合适的方法来获得这一切?
- 可测试性
- 适当的 DI / IoC
- 尽可能少的耦合
请注意,我在这里讨论的不仅仅是 MVVM 以及将视图模型放入视图中。这具体是由需要从内核提供存储库类型对象触发的,然后从该存储库中获取注入功能的实体(数据当然来自数据库,但它们还需要一些对象作为参数,具体取决于状态世界,Ninject 知道如何提供)。我可以在不将存储库和实体都留下无法测试的混乱的情况下以某种方式做到这一点吗?
如果有任何不清楚的地方,请告诉我。谢谢!
编辑 7 月 14 日
我确信提供的两个答案可能是正确的。然而,我身体的每一根纤维都在与这种变化作斗争;其中一些可能是由于缺乏知识造成的,但还有一个具体原因是我无法看到这种做事方式的优雅之处;
我在最初的问题中没有很好地解释这一点,但问题是我正在编写一个库,该库将被几个(最初是 4-5 个,以后可能更多)WPF 客户端应用程序使用。这些应用程序都在相同的域模型等上运行,因此将它们全部保存在一个库中是保持 DRY 的唯一方法。然而,这个系统的客户也有可能编写他们自己的客户——我希望他们有一个简单、干净的库可以与之交谈。我不想强迫他们在他们的 Composition Root 中使用 DI(在他的书中使用 Mark Seeman 之类的术语)——因为与他们刚刚更新 MyCrazySystemAdapter() 并使用它相比,这使事情变得非常复杂。
现在,MyCrazySystemAdapter(之所以选择这个名字是因为我知道人们在这里会不同意我的观点)需要由子组件组成,并使用 DI 组合在一起。MyCrazySystemAdapter 本身不需要注入。它是客户端与系统对话时需要使用的唯一接口。因此,客户应该高兴地获得其中之一,DI 就像幕后发生的魔术一样,并且该对象由许多不同的对象使用最佳实践和原则组成。
我确实意识到这将是一种有争议的做事方式。但是,我也知道将成为此 API 客户的人。如果他们发现他们需要学习和连接 DI 系统,并在他们的应用程序入口点(组合根)中提前创建他们的整个对象结构,而不是新建一个对象,他们会给我中指和直接弄乱数据库并以您难以想象的方式搞砸事情。
TL;DR:提供结构合理的 API 对客户来说太麻烦了。我的 API 需要交付他们可以使用的单个对象——使用 DI 和适当的实践在幕后构建。现实世界有时会胜过将所有东西倒过来以忠于模式和实践的愿望。