如何在我的工厂解析器中使用相同的抽象接口注册 2 个依赖项?

How can I register 2 dependencies with the same abstract interface in my factory resolver?

我有一个依赖容器,看起来像这样 -

public protocol DependencyContainer {
  typealias FactoryClosure = (Self) -> AnyObject
  func register<Service>(type: Service.Type, closure: @escaping FactoryClosure)
  func resolve<Service>(type: Service.Type) -> Service
}
public final class CoreDependencyContainer: DependencyContainer {

  private var services: Dictionary<ObjectIdentifier, FactoryClosure> = [:]

  public func register<Service>(type: Service.Type, closure: @escaping FactoryClosure) {
    services[ObjectIdentifier(type)] = closure
  }

  public func resolve<Service>(type: Service.Type) -> Service {
    if let service = services[ObjectIdentifier(type)]?(self) as? Service {
      return service
    }
    preconditionFailure("Could not resolve service for \(type)")
  }

}

我注册了一些服务如下:

dependencies.register(type: RemoteImageDataLoader.self, closure: { container in
  let httpClient = container.resolve(type: HTTPClient.self)
    return RemoteImageDataLoader(client: httpClient)
})

但是我想注册2个符合抽象类型的服务RemoteImageDataLoader

dependencies.register(type: RemoteImageDataLoader.self, closure: { container in
  let httpClient = container.resolve(type: HTTPClient.self)
    return RemoteImageDataLoader(client: httpClient)
})

dependencies.register(type: RemoteImageDataLoader.self, closure: { container in
  let httpClient = container.resolve(type: AuthenticatedHTTPClient.self)
    return RemoteImageDataLoader(client: httpClient)
})

这显然行不通,因为第二个条目将替换 services 字典中的第一个条目。

我试图创建一个 typealias 来代替使用,但是这不起作用。

dependencies.register(type: RemoteImageDataLoader.self, closure: { container in
  let httpClient = container.resolve(type: HTTPClient.self)
    return RemoteImageDataLoader(client: httpClient)
})

typealias AuthRemoteImageLoader = RemoteImageDataLoader

dependencies.register(type: AuthRemoteImageLoader.self, closure: { container in
  let httpClient = container.resolve(type: AuthenticatedHTTPClient.self)
    return RemoteImageDataLoader(client: httpClient)
})

在这种情况下如何注册第二个依赖项?

我想避免创建 2 个版本的 RemoteImageDataLoader,因为唯一的区别是注入的 HTTPClient 实例。

当前它不起作用,因为您正在使用 ObjectIdentifier 作为字典中的关键字,typealias 不会更改。

你基本上是在注册同一个对象两次。

创建一个符合相同接口的空协议。您还需要扩展您的接口以符合新的空接口,否则您的 resolve 方法将抛出 preconditionFailure

protocol AuthRemoteImageLoader: RemoteImageDataLoader { }
extension RemoteImageDataLoader: AuthRemoteImageLoader { }

您还可以考虑使用泛型来指定正在使用的 HTTPClient 接口,并扩展 RemoteImageDataLoader 以根据客户端类型采取相应的行动。