XServiceLocator
"渴望恰当的依赖注入?"
XServiceLocator 是一个轻量级的 Swift 库/框架,用于动态地为对象提供它们需要的依赖。该库基于服务定位模式。其想法是,对象从某个存储中获取它们的依赖。XServiceLocator 允许您在 iOS 应用程序中无缝地使用依赖注入,而无需任何后台魔法。
🔩 组件
📦 容器
存储创建注册类型实例的配置
🛠️ 解析器
通过创建类的实例来解析特定类型的实际实现,使用容器的配置
🏭 服务工厂
一个通用的工厂解决方案,用于创建泛型类型的实例
🏃♀️ 开始使用
🚶♀️ 基本步骤
- 使用任何两种
register
方法中的一种,将所有类型注册到容器中。
let container = Container()
.register(Int.self, instance: 10)
.register(Double.self) { _ in 20 }
- 无论何时需要该类型的实例,都可以使用
Resolver
的任何两种resolve
方法之一来访问它。首先从Container
获取Resolver,然后使用它来解决依赖。
let resolver = container.resolver
let intValue = try! resolver.resolve(Int.self)
let doubleValue: Double = try! resolver.resolve()
🎲 自定义对象
您还可以为协议注册自定义类型或实例,例如
// Setting up
protocol Shape {
var name: String { get }
}
class Circle: Shape {
let name = "Circle"
let radius: Double
init(radius: Double) {
self.radius = radius
}
}
class Rectangle: Shape {
let name = "Rectangle"
let width: Double
let height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
}
struct Drawing {
let shape: Shape
}
// Registering all the dependencies
let container = Container()
.register(Shape.self, instance: Circle(radius: 10))
.register(Circle.self) { _ in Circle(radius: 20) }
.register(Rectangle.self, instance: Rectangle(width: 30, height: 15))
.register(Drawing.self) { _ in
let shape = Rectangle(width: 10, height: 5)
return Drawing(shape: shape)
}
// Resolving the dependencies
let resolver = container.resolver
let rectangle = try! resolver.resolve(Rectangle.self)
let shape = try! resolver.resolve(Shape.self)
let circle: Circle = try! resolver.resolve()
let drawing: Drawing = try! resolver.resolve()
// Accessing values
print(rectangle.name) // Rectangle
print(shape.name) // Circle
print(circle.name) // Circle
print(drawing.shape.name) // Rectangle
print("\(rectangle.width), \(rectangle.height)") // 30.0, 15.0
print((shape as! Circle).radius) // 10.0
print(circle.radius) // 20.0
🎩 使用已注册的实例进行后续注册
// Registering all the dependencies
let container = Container()
.register(Double.self, instance: 30)
.register(Rectangle.self, instance: Rectangle(width: 10, height: 20))
.register(Circle.self) { resolver in Circle(radius: try! resolver.resolve()) }
// Resolving the dependencies
let resolver = container.resolver
let circle: Circle = try! resolver.resolve()
// Accessing values
circle.radius // 30.0
👶 使用(子)依赖解析器
一个容器可以有另一个解析器作为依赖,如果主解析器(容器)未能解决依赖,则可以使用该解析器进行解决。
// Registering all the dependencies
let dependency = Container()
.register(Double.self, instance: 100)
.register(Shape.self, instance: Rectangle(width: 10, height: 20))
let container = Container(dependency: dependency)
.register(Rectangle.self, instance: Rectangle(width: 15, height: 7.5))
// Resolving the dependencies
let resolver = container.resolver
let shapeRectangle = try! resolver.resolve(Shape.self) as! Rectangle
let rectangle: Rectangle = try! resolver.resolve()
let doubleValue: Double = try! resolver.resolve()
// Accessing values
print("\(shapeRectangle.width), \(shapeRectangle.height)") // 10.0, 20.0
print("\(rectangle.width), \(rectangle.height)") // 15.0, 7.5
print(doubleValue) // 100
💪 解析器数组
解析器数组也充当解析器。只要数组中的任何元素能够成功解决,就返回对象。
// Registering all the dependencies
let container = Container()
.register(Int.self, instance: 10)
.register(Double.self, instance: 20)
let container1 = Container()
.register(Float.self, instance: 30)
.register(Double.self, instance: 50)
let arrayOfResolvers: Resolver = [
container,
container1,
]
// Resolving the dependencies
let intValue = try! arrayOfResolvers.resolve(Int.self) // 10
let floatValue = try! arrayOfResolvers.resolve(Float.self) // 30.0
let doubleValue = try! arrayOfResolvers.resolve(Double.self) // 20.0
🤷♂️ 为什么使用服务定位模式呢?
- 类/对象之间的松散耦合
- 提供了更好的可测试性
- 提供可扩展性。新的实例可以轻松注册,实现可以在不进行大量更改的情况下切换。
为什么是 XServiceLocator?
- 即插即用。集成库后即可开始使用。
- 支持解包器数组。可以组合使用多个解包器来解析类型。
- 支持注册和解析任何类型。
- 由一群真正关心社区及其解决方案质量的开发者开发和维护。
- 所有内容仅使用 Swift 构建。没有 Objective-C 遗留代码。
🛠 安装
CocoaPods
要使用 CocoaPods 将 XServiceLocator
集成到 Xcode 项目中,请将以下内容添加到您的 Podfile
pod 'XServiceLocator', '~> 1.0'
Carthage
要使用 Carthage 将 XServiceLocator
集成到您 Xcode 项目中,请将以下内容添加到您的 Cartfile
github "quickbirdstudios/XServiceLocator" ~> 1.0
然后运行 carthage update
。
如果您这是第一次在项目中使用 Carthage,您需要按照以下步骤进行一些操作,具体说明请参考 Carthage。
Swift 包管理器
有关如何在您的应用程序中采用 Swift 包的更多信息,请参阅 此 WWDC 演示。
将 https://github.com/quickbirdstudios/XServiceLocator.git
指定为 XServiceLocator
包链接。
手动
如果您不希望使用任何依赖管理器,可以通过下载源代码并将文件放在您的项目目录中来手动将 XServiceLocator
集成到您的 iOS 项目中。
👤 作者
本框架是用以下方式创建的
❤️ 贡献
如果您需要帮助、发现了一个错误或想要讨论功能请求,请打开一个 issue。
如果您想要对 XServiceLocator 进行更改,请打开一个 PR。
📃 许可协议
XServiceLocator 采用 MIT 许可协议发布。有关更多信息,请参阅 License.md。