如何在Swift中实现多绑定协议实现?

时间:2015-07-20 01:34:23

标签: swift dependency-injection

假设我有一个假想的猫市场。这些猫由许多猫分销商提供,包括SPCA,Cats-R-Us和磅。我想提供一个通用接口,CatProvider可以通过它显示他们的猫。我还想允许CatProvider协议的实现者能够注册以提供猫,我的应用程序不知道它们的存在。例如:

protocol Cat {
  let name: String { get }
  let price: Float { get }
}

protocol CatProvider {
  func getCats() -> [Cat]
}

class CatService {
  func allCats() -> Set<Cat> {
    let catProviders: [CatProvider] = // Get all of the cat providers.
    return catProviders.reduce(Set<Cat>()) {
      cats, provider in
      return cats.union(Set(provider.getCats()))
    }
  }
}

我正在尝试确定允许我的CatProvider在没有CatService知识的情况下将自己多绑定到CatProvider协议的最佳方法。即我不希望CatService实例化CatProvider。可以在Swift中执行此操作吗?在Objective-C中,我会在每个文件的顶部都有一个绑定宏,但我不知道如何在这里获得相同的结果。

1 个答案:

答案 0 :(得分:0)

让我们首先添加一个NSHashTable,以便对任何自我注册的提供商保持弱引用。

class CatService {
    private let providers = NSHashTable.weakObjectsHashTable()

    // stuff
}

现在,让我们提供一种添加(如果您愿意,删除)提供商的方法:

class CatService {
    private let providers = NSHashTable.weakObjectsHashTable()

    func addProvider(provider: CatProvider) {
        providers.addObject(provider)
    }

    // optional:
    func removeProvider(provider: CatProvider) {
        providers.removeObject(provider)
    }
}

我们可以返回所有提供者或一组的数组。

作为阵列:

var allProviders: [CatProvider]? {
    return providers.allObjects as? [CatProvider]
}

作为一套:

var allProviders: Set<CatProvider>? {
    return providers.setRepresentation as? Set<CatProvider>
}

当然,如果需要,我们可以使用providers.allObjectsproviders.setRepresentation快速枚举提供商,以便我们实际使用此CatService类。< / p>