ios - swift 中查看 Controller 的依赖注入(inject)建议

标签 ios swift dependency-injection

我正在使用 Swift 制作一个 iOS 应用程序,它对组成该应用程序的大多数 View Controller 具有不同的状态。 View Controller 所依赖的少数“状态”是用户是否登录,或者地址是否已注册、搜索或丢失等。目前,数据在 prepare(for:sender) 方法。

以下是我的应用程序的结构,还有大约十几个具有类似结构的 View Controller 。

App.swift

struct App {
  enum LoginState {
    case unregistered
    case registered(User) // User defined elsewhere
  }

  enum OtherState {
    case stateOne
    case stateTwo(AssociatedType)
    case stateThree(OtherAssociatedType)
  }

  // Default states
  var loginState: LoginState = .unregistered
  var otherState: OtherState = .stateOne
}

HomeViewController.swift

class HomeViewController: UIViewController {
  var app: App!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    switch segue.identifier {
    case "Other View Controller Segue":
      let otherVC = segue.destination as! OtherViewController
      otherVC.app = app

    default:
      break
    }
}

AppDelegate.swift

class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let storybard = UIStoryboard(name: "Main", bundle: nil)
    let mainNavController = storyboard.instantiateViewController(withIdentifier: "Main Navigation Controller") as! UINavigationController
    let homeViewController = mainNavController.topViewController as! HomeViewController

    window?.rootViewController = mainNavController
    // 'injecting' app to the homeViewController
    homeViewController.app = App()

    return true
}

我找不到大约一年前第一次遇到“如何在 View Controller 之间传递数据”时找到的原始帖子,但这可能是其中之一:Passing Data between View Controllers (其中没有在任何地方提到术语依赖注入(inject))。 然后我大约一个月前听到了这个术语依赖注入(inject),这个花哨的术语似乎适合我处理类的情况(HomeViewControllerOtherViewController ) 需要处理可以具有状态的数据 (struct App)。

为了验证这种在​​ segue 中抛出 app 实例的方法,我做了几个晚上的研究。 但是现在我有太多关于以下方面的信息:several dependency injection methodologies , unit testing in swift via DI , 一些 DI 框架 here , here , here , and here , 单元测试框架 here , here ,和(现在由于缺乏声誉,我无法添加更多链接..),以及一大堆媒体/博客/SO 帖子。

问题是:1. 我是否在这里进行了所谓的依赖注入(inject),这是“正确的方法”吗? 2. 我可以吗用这种方法进行单元/UI 测试? 3. 如果我正在做的是合法的依赖注入(inject),为什么需要依赖注入(inject)框架?

依赖注入(inject)框架看起来没有必要,神秘(而且令人恐惧),至少对我来说只是想编写一个遵循 SOLID 原则的可维护应用程序。 我厌倦了抽象的概念或看似与我的情况无关的例子,所以如果有人能帮助我解决这些概念和设计决策,包括框架的需要,我会很高兴。

最佳答案

我建议避免关注不同类型 DI 的技术细节,我会关注基本概念。 DI 意味着您的 View Controller 无法自行获取所需的依赖项,而是从外部 提供依赖项。 所以您的 otherVC.app = app 是一个非常小的 DI 基本示例。

简而言之,您现在可以通过 app 的不同实例来测试您的 View Controller ,这是进行 DI 的主要目标。

你能做得更好吗?我们可能会。例如,让您的 App 对象变小一点,将“状态”分成更小的部分。 另一个改进可能是在 View Controller 中使用协议(protocol)而不是具体类型。这样,在测试期间,您可以将模拟对象作为依赖项传递,这对您的测试有很大帮助。

关于ios - swift 中查看 Controller 的依赖注入(inject)建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56908556/

相关文章:

ios - 接入点 :Error Domain = NSCocoaErrorDomain Code=3840

ios - iPhone - 最后一行在 iPhone 4 和 3GS 中不可见 UITableView

ios - 在 iOS 7 上使用图案图像设置背景颜色会导致黑色/透明屏幕

ios - 使用swift在选项卡 View 中的导航栏上添加按钮

c# - 什么是依赖注入(inject),我为什么要使用它?

java - 在 UntypedActor Play 2.5 java 中注入(inject)变量 null

ios - 在钥匙串(keychain)中存储游戏状态和分数

ios - Swift 元组作为字典值

ios - 使用自定义维度在初始化时布局单元格 subview

python - 什么是依赖注入(inject)的 Pythonic 方式?