依赖注入 pointfree.co-style:依赖与依赖?

Dependency Injection pointfree.co-style: dependencies with dependencies?

我对 pointfree.co 人设计的/talked about 依赖注入模式非常感兴趣,其中您有一个 Environment 结构,其中包含所有依赖项的可变属性。

简而言之,这个模式:

struct Environment {
  var analytics = Analytics()
  var date: () -> Date = Date.init
  var gitHub = GitHub()
}

var Current = Environment()

你可以看看他们的基本例子here, and a bigger one here

虽然我想做的是能够拥有需要依赖性的依赖性。例如,需要网络提供商才能 post 一些数据的分析跟踪器。

import Foundation

// MARK: - NetworkProvider

struct NetworkProvider {
  var postData = { (data: Data) in
    print("Data posted using the `NetworkProvider`")
  }
}

extension NetworkProvider {
  static let mock = NetworkProvider(
    postData: { data in
      print("Mock post!")
    }
  )
}


// MARK: - Tracker

struct Tracker {
  var networkProvider = NetworkProvider()

  var track = { (event: String) in
    print("Tracked: \(event)")
    let data = event.data(using: .utf8)!
    networkProvider.postData(data) // <- ERROR
  }
}

extension Tracker {
  static let mock = Tracker(
    networkProvider: .mock,
    track: { event in
      print("Mocked tracked: \(event)")
    }
  )
}


// MARK: - Environment

struct Environment {
  var networkProvider = NetworkProvider()
  var tracker = Tracker()
}

extension Environment {
  static let mock = Environment(
    networkProvider: .mock,
    tracker: .mock
  )
}

上面的代码无法编译:Instance member 'networkProvider' cannot be used on type 'Tracker',这完全有道理。我可以将 networkProvider 属性 变成 static var 但是我不能再传递模拟版本,所以这没有帮助。

我怎样才能使用这种依赖注入方法,同时使依赖需要依赖成为可能?

您无法在计算的 属性 中直接访问 self,但如果您将其声明为 lazy 变量

则可以
lazy var track = { [self] (event: String) in ...