Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Koin MPP入門

Koin MPP入門

85637f06e3366e5cc4c84780cc346141?s=128

RyuNen344

July 29, 2021
Tweet

Transcript

  1. Koin MPP入門 2021.07.29 Kotlin Multiplatform Mobile勉強会 Wantedly × チームラボ #2

    Bujiro Miyoshi
  2. About Me 三好文二郎(みよし ぶんじろう) • チームラボ所属 • androidエンジニア歴3年ぐらい(なはず) • JVM系のserver

    frameworkも触れる • SNSのアイコンがシンバルだったりブロッコリー頭
  3. What is Koin? • DSLで書ける軽量なDIコンテナライブラリ • 実行時にDependency Graphを構築する ◦ 内部でinstanceをhashMapで管理する

    • android用拡張定義(ViewModel, Service, WorkManger, Compose….)も豊富ですが今日はあんまり触れない • 3.0.0からMPPに対応
  4. Simple Usage // declare dependency val sampleModule = { //

    singleton single { Repository() } // new instance each time factory { Factory() } // instance depends on scope scope { Scoped() } } // constructor injection val sampleModule = { single { Repository(get(), get()) } } // parameter injection val repository: Repository by inject()
  5. Simple Usage // start a KoinApplication in Global context startKoin

    { moudles(sampleModule) }
  6. // match type ServiceImpl only single { ServiceImpl() } //

    match type Service only single<Service> { ServiceImpl() } // match type Service only single { ServiceImpl() as Service } // match types ServiceImpl & Service single { ServiceImpl() } bind Service::class • koinはKlassをkeyにして instanceをmapで管理 している • mapに複数のkeyに対し て設定できる Type Binding
  7. val scopedModule = module { // scope owner scope<ScopeOwner> {

    // new instance each scope owner scoped { InstancePrinter() } } } • instanceのlifecycleを あるクラスに紐づける • scope ownerは KoinScopeComponen tの実装が必要 Scope
  8. val qualifierModule = module { // string single(named("namedQualifier")) { InstancePrinter()

    } // type single(qualifier<KlassQualifier>()) { InstancePrinter() } // enum single(Mobile.IOS.qualifier) { InstancePrinter() } single(Mobile.ANDROID.qualifier) { InstancePrinter() } } • Klassに追加して情報を 付与してinstance管理さ せる Qualifier
  9. 拡張関数とDelegateが豊富で便利🤗 (kotlin側は)

  10. Swiftから呼び出しずらい😨

  11. Why not useful on swift? obj-C Class != Klass obj-C

    Protocol != Klass
  12. Get instance from container fun <T> get( clazz: KClass<*>, qualifier:

    Qualifier? = null, parameters: ParametersDefinition? = null ) Klassを使ってinstanceを生成する
  13. Create TypeQualifier class TypeQualifier(val type: KClass<*>) : Qualifier { ....

    } Klassを使ってQualifierを生成する
  14. obj-C to Klass • kotlinx.cinteropに関数が定義されてる fun getOriginalKotlinClass(objCClass: ObjCClass): KClass<*>? fun

    getOriginalKotlinClass(objCProtocol: ObjCProtocol): KClass<*>?
  15. Get instance from container fun Koin.get(objCClass : ObjCClass, qualifier :

    Qualifier? = null) : Any { val kClazz = getOriginalKotlinClass(objCClass)!! return get(kClazz, qualifier, null) } fun Koin.get(objCProtocol : ObjCProtocol, qualifier : Qualifier? = null) : Any { val kClazz = getOriginalKotlinClass(objCProtocol)!! return get(kClazz, qualifier, null) } こんな拡張関数を作成する
  16. Get instance from container🍎 koin.get(objCClass: Repository.self, qualifier: nil) as! Repository

    koin.get(objCProtocol: Repository.self, qualifier: nil) as! Repository すっきり呼べるようになった🤗
  17. Get instance from container extension KoinApplication { func get<T, R>(prot:

    T, qualifier: Qualifier? = nil) -> R where T : Protocol { return koin.get(objCProtocol: prot, qualifier: qualifier) as! R } func get<T, R>(klass: T, qualifier: Qualifier? = nil) -> R { return koin.get(objCClass: klass as! AnyClass, qualifier: qualifier) as! R } } こんな拡張関数を作成してあげると・・・
  18. Get instance from container🍎 koinApplication.get(klass: Repository.self) koinApplication.get(klass: RepositoryImpl.self) もっとすっきり呼べるようになった🤗

  19. Create TypeQualifier fun typeQualifier(objCProtocol : ObjCProtocol) : TypeQualifier { val

    kClazz = getOriginalKotlinClass(objCProtocol)!! return TypeQualifier(type = kClazz) } fun typeQualifier(objCClass : ObjCClass) : TypeQualifier { val kClazz = getOriginalKotlinClass(objCClass)!! return TypeQualifier(type = kClazz) } こんな拡張関数を作成する
  20. Create TypeQualifier KoinExtKt.typeQualifier(objCClass: KlassQualifier.self) すっきり呼べるようになった🤗

  21. アプリ起動するときになってModule定義 が間違ってるってクラッシュするんだけ ど。。。。

  22. android側でModule定義のテスト書けま す😉

  23. Check module definitions • 主要なmocking libraryがkotlin Nativeに対応していないためJVMの みでテスト可能 • koin-test-junit4

    or koin-test-junit5とmockito, mockkを組み合わ せてテスト可能
  24. Check module definitions class CheckModuleTest : KoinTest { @get:Rule val

    mockProvider = MockProviderRule.create { clazz -> mockkClass(clazz) } @Test fun testExample() { checkModules { modules(sampleModule) } } }
  25. Sample is Here 👇 https://github.com/RyuNen344/koin-mpp-sample