Swoin 0.0.5

Swoin 0.0.5

Adam Polt 维护。



Swoin 0.0.5

  • 作者
  • Adam Polt

Swoin

Swoin 是一个 Swift 依赖注入框架,受 Koin 启发

开始使用

将框架添加到项目中,例如使用 Cocoapods

pod 'Swoin'

将依赖项添加到某些模块中,然后传递给 startSwoin 生成器以启动全局 Swoin 实例

class SwoinCreator: SwoinComponent {
    //...

    func start() {
        let appModule = Module {
            single { CustomNavigationController() }
                .bind(UINavigationController.self)

            weak(named: "TestSubject") { PublishSubject<Void>() }
                .bind(Observable<Void>.self) { $0.asObservable() }
                .bind(AnyObserver<Void>.self) { $0.asObserver() }

            weak { HomeViewModel(input: get(), output: get()) }
            weak { HomeViewController(viewModel: get(), view: get()) }
            weak { HomeView() }
        }

        let thingModule = Module {
            factory { Thing() }

            single { ThingFetcher(thing: get()) }
                .bind(IntFetcher.self)
                .bind(StringFetcher.self)
        }
        
        startSwoin {
            appModule
            thingModule
            logger(Swoin.printLogger)
        }
    }
}

使用 @Inject 懒加载字段

@Inject private var navigationController: CustomNavigationController

或使用 get() 强加载

let controller: TipsViewController = get()
    
rootViewController.pushViewController(controller, animated: true)

请注意,get() 只能用于实现 SwoinComponent 的调用类

// This is fine:
struct Cowboy: SwoinComponent {
    var horse: Horse = get()
}

// This will not compile, "Cannot find 'get' in scope":
struct Horse {
    let saddle: Saddle = get()
}

支持命名依赖项

@Inject(named: "TestSubject") private var testObservable: Observable<Void>
    
let observer: PublishSubject = get(named: "TestSubject")

缓存类型

支持三种缓存策略

  • 只要模块保持加载状态,就创建一次 single 依赖项,即单例
  • 在解析任何时间都重新创建 factory 依赖项
  • 如果没有其他强引用到该类型的任何先前创建的实例,则重新创建 weak 依赖项

绑定其他类型

您可以使用.bind将多个类型绑定到依赖注册,并传递一个可选的闭包以将其转换为该类型。

    weak(named: "TestSubject") { PublishSubject<Void>() }
            .bind(Observable<Void>.self) { $0.asObservable() }
            .bind(AnyObserver<Void>.self) { $0.asObserver() }

绑定的类型与其所绑定依赖项具有相同的名称和缓存策略。

如果原始类型实现了协议,则闭包是可选的,因为默认是{ $0 as! NewType },但显然如果在运行时强制转换不可行,这会导致程序崩溃。

初始化之后的代码运行

您可以使用.then在依赖项初始化后执行一个动作。

    private class CircularDependencyOne {
        let dependencyTwo: CircularDependencyTwo

        init(_ dependencyTwo: CircularDependencyTwo) {
            self.dependencyTwo = dependencyTwo
        }
    }

    private class CircularDependencyTwo {
        var dependencyOne: CircularDependencyOne?
    }
    
    let testModule = Module {
            single { CircularDependencyOne(get()) }
                .then {
                    $0.dependencyTwo.dependencyOne = $0
                }

            single { CircularDependencyTwo() }
    }