【发布时间】:2021-05-10 09:06:15
【问题描述】:
我一直在从事一项需要我专注于依赖注入的工作。对于后人,我在 Swift/SwiftUI 中使用它,尽管我相信我对概念的理解比语言更固有。
我创建了一个依赖注入容器,可以用来注册和解析类型和组件。因此;
protocol MyContainerProtocol {
func register<Component>(type: Component.Type, component: Any)
func resolve<Component>(type: Component.Type) -> Component?
}
final class MyContainer: MyContainerProtocol {
static let shared = DependencyContainer()
private init() { }
var components: [String: Any] = [:]
func register<Component>(type: Component.Type, component: Any) {
components["\(type)"] = component
}
func resolve<Component>(type: Component.Type) -> Component? {
return components["\(type)"] as? Component
}
}
这将在下面变得相关,但我的项目中有一个名为 VideoProcessor 的类;
class VideoProcessor: SomeProtocol {
var codec: String
var format: String
init(codec: String, format: String) {
self.codec = codec
self.format = format
}
}
在应用程序生命周期的早期,我正在注册组件。例如;
let container = DependencyContainer.shared
container.register(type: VideoProcessor.self, component: VideoProcessor(codec: "H264", format: "MP4"))
...
let processor = container.resolve(type: VideoProcessor.self)!
我的困惑:要求我解决一个类型的实例,而不必在注册时构造它。实际上,每次解析注册类型的新实例时,都会要求我解析它。在我看来,这意味着我的代码类似于:
let container = DependencyContainer.shared
container.register(type: VideoProcessor.self)
...
let processorA = container.resolve(type: VideoProcessor.self)!
processorA.codec = "H264"
processorA.format = "MP4"
let processorB = container.resolve(type: VideoProcessor.self)!
processorB.codec = "H265"
processorB.format = "MOV"
但是,VideoProcessor 有它自己的依赖项,导致我不确定如何注册类型。
我不确定我的问题是否存在于我的 Dependency Container 的构建方式、我的类的构建方式,或者我只是不理解所问的问题。即使查看像 Swinject 或 DIP 这样的流行 Swift 库,我也没有完全看到我的 Container 做错了什么(或者如果这是使用 Factory 方法的地方)。
【问题讨论】:
-
如果您每次都需要创建一个新的实例,您可以注册一个
(DependencyContainer) -> Component函数,而不是一个已经构造好的对象。依赖容器部分在那里,因此您可以解决已注册的任何依赖项。绝对有必要从头开始构建它而不是使用库吗?我从未亲自使用过 Swinject 或 DIP,但它们可能已经解决了您遇到或将要自己构建的许多问题。 -
感谢您的回复@Steven0351。如果我遵循您的评论,您是否建议在我的依赖容器中创建一个新函数,该函数在调用时会返回给定类的新实例化实例?这在实践中听起来很简单,但是根据我的 VideoProcessor 示例,当实例本身具有依赖项(而不是变量)时,我将如何处理返回实例?可以提供样品吗?
-
我发布了一个答案,以便提供比 cmets 中更详细的示例。
-
谢谢@Steven0351!我正在审查您的答案并努力消化知识并尝试一下。感谢您的帮助!
标签: swift dependency-injection inversion-of-control ioc-container