测试已测试 | ✗ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2024年1月 |
SPM支持 SPM | ✗ |
由 Martin Eberl 维护。
要运行示例项目,克隆仓库,然后首先从 Example 目录运行 pod install
。
SwiftDependencyInjection 通过 CocoaPods 提供。要安装
它,只需将以下行添加到您的 Podfile 中
pod 'SwiftDependencyInjection'
Martin Eberl, [email protected]
SwiftDependencyInjection 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。
import SwiftDependencyInjection
protocol FooProvider {
var foo: Foo { get }
}
final class FooModule: Module, FooProvider {
weak var delegate: ModuleDelegate?
lazy var foo: Foo = {
return Foo()
}()
}
使用协议(此处为 FooProvider)来帮助进行通信和请求注入类型。
Injector.shared.inject(self).with(FooProvider.self)
这有助于注入器为您提供所需的依赖项。添加 .with(…Provider.self) 以请求更多依赖项。
func inject(inject: Any) {
if let inject = inject as? FooProvider {
foo = inject.foo
}
}
假设一些模块需要请求其他模块的依赖项。您可能希望注入器完成这项艰难的工作并解决这些依赖项。
这里有一个 LectureProvider,它向学生提供讲座的存储库。
import SwiftDependencyInjection
protocol LectureProvidable {
var repository: LectureRepository { get }
}
final class LectureProviderModule: Module, LectureProvidable {
weak var delegate: ModuleDelegate?
//lazy makes a var to a singleton
lazy var repository: LectureRepository = {
return LectureRepository()
}()
}
现在根据我们学生的数量,我们想得到一个房间,或者在音乐厅仍然过于拥挤的情况下,我们需要在户外举行讲座
enum Room: Int {
case lectureRoom = 20
case lectureHall = 50
case auditorium = 300
statuc func for(_ numberOfStudents: Int) -> Room? {
if numberOfStudents <= Room.lectureRoom.rawValue {
return .lectureRoom
}
if numberOfStudents <= Room.lectureHall.rawValue {
return .lectureHall
}
if numberOfStudents <= Room.lectureHall.rawValue {
return .auditorium
}
return nil
}
func holdLecture(_ lector: Lector) {}
}
import SwiftDependencyInjection
protocol RoomProvidable {
func room(for lectureId: String) -> Room?
}
final class RoomProviderModule: Module, RoomProvidable {
weak var delegate: ModuleDelegate?
weak var lectureRepository: LectureRepository?
init() {
//this is how you tell the the Injector, what types of provideables are
//required for e.g. the RoomProvideable
//The Roomprovideable is not being provided, unless it's dependencies can
//be resolved
requires(for: RoomProvidable)?
.this(LectureProvidable.self)
//.this(... .self) we would add here more dependencies if we needed to
}
func room(for lectureId: Int) -> Room? {
guard let lecture = lectureRepository.lectures(with: lectureId) else {
return nil
}
return Room.for(lecture.subscibedStudents)
}
func inject(inject: Any) {
if let inject = inject as? LectureProvidable {
lectureRepository = inject.repository
}
}
}
现在我们需要注册模块
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//we wont to register the Moduels
//The Injector has a built in dependency resolve,
//so it resolved the conflict, that the RoomProvider is
//first instantiated, even though it needs the LecutureProvider Module.
//When the LectureProviderModule provides it's Provideables, the RoomProvider is
//automatically injected with the required dependencies
RoomProviderModule().provide()
LectureProviderModule().provide()
return true
}
...
}
最后,我们希望讲师提供讲座,学生可以注册,并且应根据学生数量自动选择房间
final class Lector {
var roomProvidable: RoomProvidable?
var lectureProvidable: LectureProvidable?
init() {
//That's how you say, what dependencies you need
Injector.shared.inject(self)
.with(RoomProvidable.self)
.with(LectureProvidable.self)
}
//this is required, because that's how the Injector assigns the dependencies
func inject(inject: Any) {
if let inject = inject as? RoomProvidable {
roomProvidable = inject
}
if let inject = inject as? LectureProvidable {
lectureProvidable = inject
}
}
func provideLecture(lectureId: Int) {
guard let lectureProvidable = lectureProvidable else {
return
}
lectureProvideable.provide(Lecture(id: lectureId, lector: this, Date(2017, 12, 03), estimatedHours: 2))
}
func holdLecture(lectureId: Int) {
guard let roomProvidable = roomProvidable,
let room = roomProvidable.room(for: lectureId) else {
//hold lecture outside
return
}
room.holdLecture(this)
}
}
类注入
仅用几行代码,您就可以更轻松地添加依赖项
private var fooProvider = Inject<FooProvider>()
...
fooProvider.value
如果您需要任何其他示例或有改进建议,我将不胜感激