一个简单的依赖注入框架,用于 Swift,受 Typhoon 启发。它使用组件作为对象工厂来执行注入和对象配置。
对象定义的语法已经简化并易于使用。它与 Typhoon 的语法有所不同,但有一些类似元素,这使学习更容易。
public var object:TheObject {
return self.define() { (definition) in
let object1 = definition *~> Object1()
object1.object2 = self.assembly2.object2
return object1
}
}
每个可注入对象都被定义为组件的计算属性。对象本身是通过调用组件的 define
方法来创建的,并使用对象注入定义闭包。定义对象应使用 initObject
方法或通过 *~>
运算符来初始化对象,以正确解决循环依赖。
对象初始化作用域可以是 Singleton
、ObjectGraph
或 Prototype
。
Singleton - 这是一个懒加载单例。它在第一次属性访问时创建。此类对象定义闭包只调用一次。
ObjectGraph - 此作用域为每个对象图创建一个对象副本。解决循环依赖,但可能会导致保持循环。
Prototype - 此作用域在每次属性请求时创建对象的副本。原型中循环依赖会导致无限循环。
作用域的对象定义
return self.define(withScope: .Singleton) { (definition) in
return self.define(withKey: "TheObject", scope: .Singleton) { (definition) in
由于缺少运行时功能,对象实例通过 keys
存储在组件对象堆栈中。如果未设置键,则将使用对象类型名称作为键。在有多个相同类型对象的情况下,它直到一个对象图中有两个或多个对象时才会正常工作。
对象是作为组件的 define
方法的返回结果。此方法检查作用域。对于 .Prototype
,它调用注入块。对于 .Singleton
和 .ObjectGraph
,它检查当前对象图堆栈中是否已存在对象实例,使用 key
检查实例是否存在。现有实例以原样返回。如果对象未在堆栈中找到,它将调用注入块。
注入块将以 definition
对象为参数被调用,该对象包含对象 key
、scope
和 assembly
,并将对象初始化块重定向到组件的对象实例化方法。
在实例化对象时,Assembly会检查定义中的scope
和key
。对于.Prototype
,它只是调用initBlock。对于.ObjectGraph
,它会检查当前对象图栈中是否存在该对象实例,是否使用key
。找到的实例直接返回。如果栈中未找到对象,它会调用注入块。对于.Singleton
,它会检查assembly的单例列表,如果对象实例存在,则会使用key
进行检查。找到的实例直接返回。如果单例列表中未找到对象,它会调用注入块。
循环依赖通过对象栈和深度解决。每次调用define
都会在调用注入块之前增加栈深度,并在之后减少。如果注入块调用后的栈深度为零,则对象栈将被销毁。
带有键的对象定义
return self.define(withKey: "TheObject") { (definition) in
return self.define(withKey: "TheObject", scope: .Singleton) { (definition) in
SwiftInjections可以用于将数据注入现有对象。此外,可以使用现有对象来创建循环依赖。注入到现有对象的应该是一个以对象为参数的函数。此对象应在该初始化块内使用,而不是在构造函数中使用。
以下是一个示例
public func injectIntoObject( inputObject:Object )->Object {
return self.define() { (definition) in
let object = definition *~> inputObject
object.anotherObject = self.anotherObject
return object
}
}
public var anotherObject:AnotherObject {
return self.define() { (definition) in
let anotherObject = definition *~> AnotherObject()
anotherObject.object = self.existingObjectByMatchingType()
return anotherObject
}
}
方法existingObjectByMatchingType
通过当前对象图的对象类型作为键返回对象。也可通过existingObject(withKey:)
方法显式设置键。
要运行测试项目,请克隆存储库,然后首先从Example目录运行pod install
。
SwiftInjections可以通过CocoaPods获得。要安装它,只需将以下行添加到Podfile中
pod "SwiftInjections"
Andrey Zarembo,[email protected]
SwiftInjections可在MIT证书下获得。有关更多信息,请参阅LICENSE文件。