swift 的新手,我试图创建一个服务注册表:
class ServiceRegistry {
static var instance = ServiceRegistry()
private var registry = [String:AnyObject]()
private init(){}
func register<T>(key:T, value:AnyObject) {
self.registry["\(T.self)"] = value
}
func get<T>(_:T) -> AnyObject? {
return registry["\(T.self)"]
}
}
但不是 super 友好:
注册:
ServiceRegistry.instance.register(CacheServiceProtocol.self, value:ImageCacheService())
检索:
if let cache = ServiceRegistry.instance.get(CacheServiceProtocol) as? CacheServiceProtocol { ... }
有什么更好的方法吗?去掉 as 会有用吗?
if let ...
最佳答案
Swinject 是 Swift 的依赖注入(inject)框架。在您的情况下,您可以在不使用 as?
的情况下使用它。
注册:
let container = Container()
container.register(CacheServiceProtocol.self) { _ in ImageCacheService() }
检索:
let cache = container.resolve(CacheServiceProtocol.self)!
这里cache
被推断为CacheServiceProtocol
类型。如果指定的类型未注册,则 resolve
方法返回 nil
。我们知道 CacheServiceProtocol
已经注册,所以使用 !
的强制解包。
更新
我没有完全回答这个问题。移除转换的实现是在 registry
中存储工厂闭包而不是值。这是例子。我还修改了 key
的类型。
class ServiceRegistry {
static var instance = ServiceRegistry()
private var registry = [String:Any]()
private init(){}
func register<T>(key:T.Type, factory: () -> T) {
self.registry["\(T.self)"] = factory
}
func get<T>(_:T.Type) -> T? {
let factory = registry["\(T.self)"] as? () -> T
return factory.map { $0() }
}
}
注册:
ServiceRegistry.instance.register(CacheServiceProtocol.self) {
return ImageCacheService()
}
检索:
// The type of cache is CacheServiceProtocol? without a cast.
let cache = ServiceRegistry.instance.get(CacheServiceProtocol.self)
使用 @autoclosure
可能也不错。
关于swift - 有没有比这更好的方法在 Swift 中进行依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30769864/