swift - 有没有比这更好的方法在 Swift 中进行依赖注入(inject)?

标签 swift generics design-patterns dependency-injection

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 ...

中的 CacheServiceProtocol

最佳答案

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/

相关文章:

ios - 应用程序连接错误 : AppConnect cannot be instantiated directly

swift - 自定义键盘字体错误

ios - UITextView 中的 HTML 格式

java - @SuppressWarnings( "unchecked") 使用通用通配符时

c# - 如何创建 C# 按钮数组?

c++ - 设计模式,将数据添加到类(第 3 方)而不修改它

design-patterns - UML类图中伪代码注解对应的是什么

ios - CAShapeLayer 左上角缺少像素

javascript - 用于处理私有(private)函数的 jQuery 插件设计模式(常见做法?)

c# - 涉及 Controller 和存储库的 c# 泛型问题