我习惯在Web应用程序中使用IoC/DI - 主要是Ninject与MVC3一起使用。我的控制器已经为我创建,所有依赖项都已就位,包括子依赖项等。
然而,在厚客户端应用程序中情况不同。我必须创建自己的对象,或者我必须回到服务定位器样式的方法,其中我通过某个接口(可能是为了可测试性)要求内核给我一个完整的带有依赖项的对象。
但是,我已经看到有几个地方将服务定位器描述为反模式。
因此,我的问题是 - 如果我想在我的厚客户端应用程序中受益于Ninject,是否有更好/更适当的方法来完成所有这些操作?
测试性 适当的DI / IoC 尽可能少的耦合
请注意,我不仅谈论MVVM并将视图模型放入视图中。这是特别由需要从内核提供存储库类型对象触发的,并且然后从该存储库检索注入了功能的实体(当然,数据来自数据库,但还需要根据世界状态提供一些对象作为参数,而Ninject知道如何提供)。我是否可以在不使存储库和实体成为无法测试的混乱的情况下完成此操作?
如果有任何不清楚的地方,请告诉我。谢谢!
编辑7月14日
我确信提供的两个答案可能是正确的。但是,我的每一个细胞都在抵制这种变化;其中一部分可能是由于缺乏知识,但还有一个具体原因,我很难看到这种做事方式的优雅之处;
我没有在原始问题中足够清楚地解释这一点,但是事实是,我正在编写一个将由几个(首先是4-5,以后可能更多)WPF客户端应用程序使用的库。这些应用程序都在同一领域模型等上运行,因此将其全部放在一个库中是保持DRY的唯一方法。但是,该系统的客户还有可能编写自己的客户端 - 我希望他们拥有一个简单,干净的库来进行交流。我不想强迫他们在组合根中使用DI(像Mark Seeman在他的书中使用的那样)-因为与他们只是新建一个MyCrazySystemAdapter()并使用它相比,这会大大复杂化事情。
现在,MyCrazySystemAdapter(名称选择因为我知道人们会不同意我)需要由子组件组成,并使用DI组合。 MyCrazySystemAdapter本身不应该需要注入。它是客户端与系统交流的唯一接口。因此,客户端应该愉快地得到其中之一,DI在幕后自动完成,并且使用最佳实践和原则组成了许多不同的对象。
我知道这种想法可能会引起争议。但我也了解将成为此API客户的人员。如果他们发现需要学习和连接DI系统,并在应用程序入口点(组合根)中预先创建整个对象结构,而不是新建单个对象,他们会对我竖中指,直接与数据库打交道,并以你难以想象的方式搞砸事情。
简而言之,提供一个正确构造的API对客户来说太麻烦了。我的API需要提供一个单一的对象-在幕后使用DI和适当的实践构造-供他们使用。现实有时会胜过为了保持模式和实践而反向构建所有内容的愿望。
然而,在厚客户端应用程序中情况不同。我必须创建自己的对象,或者我必须回到服务定位器样式的方法,其中我通过某个接口(可能是为了可测试性)要求内核给我一个完整的带有依赖项的对象。
但是,我已经看到有几个地方将服务定位器描述为反模式。
因此,我的问题是 - 如果我想在我的厚客户端应用程序中受益于Ninject,是否有更好/更适当的方法来完成所有这些操作?
测试性 适当的DI / IoC 尽可能少的耦合
请注意,我不仅谈论MVVM并将视图模型放入视图中。这是特别由需要从内核提供存储库类型对象触发的,并且然后从该存储库检索注入了功能的实体(当然,数据来自数据库,但还需要根据世界状态提供一些对象作为参数,而Ninject知道如何提供)。我是否可以在不使存储库和实体成为无法测试的混乱的情况下完成此操作?
如果有任何不清楚的地方,请告诉我。谢谢!
编辑7月14日
我确信提供的两个答案可能是正确的。但是,我的每一个细胞都在抵制这种变化;其中一部分可能是由于缺乏知识,但还有一个具体原因,我很难看到这种做事方式的优雅之处;
我没有在原始问题中足够清楚地解释这一点,但是事实是,我正在编写一个将由几个(首先是4-5,以后可能更多)WPF客户端应用程序使用的库。这些应用程序都在同一领域模型等上运行,因此将其全部放在一个库中是保持DRY的唯一方法。但是,该系统的客户还有可能编写自己的客户端 - 我希望他们拥有一个简单,干净的库来进行交流。我不想强迫他们在组合根中使用DI(像Mark Seeman在他的书中使用的那样)-因为与他们只是新建一个MyCrazySystemAdapter()并使用它相比,这会大大复杂化事情。
现在,MyCrazySystemAdapter(名称选择因为我知道人们会不同意我)需要由子组件组成,并使用DI组合。 MyCrazySystemAdapter本身不应该需要注入。它是客户端与系统交流的唯一接口。因此,客户端应该愉快地得到其中之一,DI在幕后自动完成,并且使用最佳实践和原则组成了许多不同的对象。
我知道这种想法可能会引起争议。但我也了解将成为此API客户的人员。如果他们发现需要学习和连接DI系统,并在应用程序入口点(组合根)中预先创建整个对象结构,而不是新建单个对象,他们会对我竖中指,直接与数据库打交道,并以你难以想象的方式搞砸事情。
简而言之,提供一个正确构造的API对客户来说太麻烦了。我的API需要提供一个单一的对象-在幕后使用DI和适当的实践构造-供他们使用。现实有时会胜过为了保持模式和实践而反向构建所有内容的愿望。
GetStuff()
方法像是穿着礼服的服务定位器,不要这么做。(你回答中的其他部分没有问题,但服务定位器的特性使得它们无关紧要。) - Ruben Bartelink