MVVM,依赖注入和太多构造函数参数

Gui*_*oMB 7 dependency-injection mvvm ios

我使用MVVM和依赖注入进行了几个月的iOS开发,我对结果非常满意.代码非常清晰,更容易测试.但我一直在解决一个问题,我没有找到一个我觉得非常舒服的解决方案.

为了理解这个问题,我想给你一些上下文.我工作的最后一个应用程序是按以下方式/层构建的:

  • 模型
  • 查看模型
  • 查看/查看控制器
  • 服务:知道如何处理Twitter,Facebook等外部服务的类.
  • 存储库:存储库是一个知道如何与应用程序的REST API资源交互的类.可以说我们有一个博客应用程序,我们可以拥有用户资源和帖子资源.每种资源都有几种方法.资源和存储库之间存在一对一的关系.

当应用程序启动时,我们有一个Bootstrap类,用于初始化应用程序并创建主视图模型.我们有一个限制,即只有视图模型才能创建其他视图模型.例如,在具有包含元素列表的视图的情况下(在iOS中它将用UITableView表示)和每个thoses元素的详细视图,通过在点击元素后将其推送到导航堆栈来呈现在列表中.我们所做的是使附加到表视图控制器的视图模型创建详细视图模型.表视图控制器侦听表视图模型,然后通过创建详细视图控制器并将其视图模型传递给它来呈现详细视图模型.因此视图控制器不知道如何创建视图模型,它只知道如何为该视图模型创建视图控制器.

父视图模型的责任是将所有依赖项传递给子视图模型.

当视图层次中非常深的视图模型需要其父控制器不需要的依赖项时,就会出现问题.例如,访问某些外部Web服务的服务.因为它的父项没有那个依赖项,所以它必须将它添加到它的依赖列表中,从而为构造函数添加一个新参数.想象一下,如果祖父母也不具备这种依赖性,情况会怎样.

您认为什么是好的解决方案?可能的解决方案:

  • 单身人士:更难测试,他们基本上是全球状态
  • 工厂类:我们可以使用一组知道如何创建某些类型对象的工厂.例如ServiceFactory和RepositoryFactory.服务工厂可以使用方法来创建服务,例如:TwitterService,FacebookService,GithubService.存储库工厂可以知道如何为每个API资源创建存储库.在拥有少数工厂(2或3)的情况下,所有视图模型都可能依赖于这些工厂.

目前我们选择了工厂级解决方案,因为我们不需要使用单件,我们可以将工厂视为任何其他依赖性,这使得它相对容易测试.问题是,它有点像一个好的对象,并且通过拥有一个工厂,你实际上并不知道哪个是需要视图模型的真正依赖,除非你查看构造函数的实现来检查调用哪些工厂方法.

Mik*_*son -2

看来您需要使用托管扩展性框架(MEF) ,您可以在此处找到更多信息。

本质上,这将允许您做的是使用[Export][Import]属性。这将允许注入类的依赖项,而不必担心父视图模型上的大量构造函数。