2024.10.01
自社の社内情報を未来の“ゴミ”にしないための備え 「情報量が多すぎる」時代がもたらす課題とは?
Koin MPP入門(全1記事)
リンクをコピー
記事をブックマーク
三好文二郎氏(以下、三好):「Koin MPP入門」ということで、お話ししようと思います。チームラボ株式会社の三好と申します。
簡単に自己紹介をします。Androidエンジニアになって3年ちょっと経ちました。主に「Spring」ですが、JVMのserver frameworkも触ります。SNSのアイコンは、シンバルだったりブロッコリー頭だったりするので、ぜひ探してみてください。よろしくお願いします。
まず簡単に「Koin」について紹介します。KoinはDSLで書ける軽量なDIコンテナライブラリです。今日は、すごく難しい使い方を紹介するのではなく、Multiplatformができるようになったので、簡単な使い方を紹介しようと思っています。
Koinは、Androidでよく使われるDIライブラリの「Dagger」とは違って、実行時に依存性のGraphの構築をします。内部では、instanceをhashMapで管理しています。
Android用の拡張、例えばViewModel、Service、WorkManager、Composeなどの対応が進んでいます。Serverでいえば、ケイター用のライブラリもあるのですが、今日はあまり触れません。3.0.0からMultiplatformに対応しました。
最初に基本的な使い方を紹介します。一番左の、sampleModuleという定数を宣言します。その中で、DSLで依存性を宣言していくのですが、singleで囲うとRepositoryのinstanceがsingletonで管理されます。
factoryで宣言すると、Factoryクラスのinstanceが毎回生成されます。あとでもう少し詳しく説明しますが、あるinstanceのlifecycleを、あるクラスのinstanceのlifecycleにひもづける時に、scopeで宣言します。
あるクラスにconstructor injectionをしたい場合ですが、引数は、get、もしくはpage injectionの対応をしています。また、あるクラスの中でフィールドとして使いたい時には、by injectのDelegateで、instanceを引っ張ってきます。
宣言を書いたら、startKoinという関数を呼び出して、先ほど定義したModuleをmodulesの中に書きます。こうすることで、instanceのhashMapで管理してくれるようになります。
次に、Type Bindingについて説明します。Koinは、KClassをよしなにStringのIDにして、それをkeyにしてhashMapで管理しています。
1つのmapに対して、複数のkeyを設定することもできます。一番上のコードでいえば、singel{ServiceImpl()}と宣言すると、ServiceImplクラスのinstanceを取ってくる時にしか引っ掛かりません。
2番目の、singleのジェネリクスのServiceインターフェイスにすると、ServiceインターフェイスでしかServiceImplクラスのinstanceが引っ張ってこられません。
single{ServiceImpl() as Service}というかたちで、型をダウンキャストしてしまうと、Serviceクラスでしか引っ張ってこられません。
single{ServiceImpl()} bind Service、インターフェイスというかたちに宣言すると、ServiceImplクラスとServiceインターフェイスの両方に引っ掛かって、instanceを取得できるようになります。
先ほどあとで少し説明しますと話した、Scopeですね。instanceのlifecycleを、あるクラスのinstanceのlifecycleにひもづけます。scopeのownerクラスに対しては、KoinScopeComponentというインターフェイスがあるので、それの実装が必要です。Moduleの宣言は、右に書いてあるかたちになります。
ScopeOwnerクラスを、コンストラクタで普通にinstanceを生成すると、今だとInstancePrinterというクラスのinstanceを生成して、先ほど作ったScopeOwnerクラスのinstanceを破棄します。
今だとすごくシンプルな書き方をしているので、ほぼ意味はないのですが、一緒にInstancePrinterをKoinのmapから削除できます。
次に、Qualifierです。先ほどKoinはKotlinクラスのmapで管理していると言ったのですが、それに余分な情報を追加してinstance管理させることができます。
付与できる情報は、StringとTypeとEnumの3種類です。namedという関数、もしくはqualifireのジェネリクスでクラスを指定。もしくは、Enumに対して、qualifireという拡張関数が定義されているので、それを使ってEnumを指定して、同一クラスを複数種類管理させることができます。
パッとコード見てもらうとわかると思うのですが、拡張関数とDelegateがすごくたっぷりあるので、特にKotlin側で簡単に使う分にはすごく便利です。
「Swift」からはすごく呼びづらいですね。Swiftから呼びづらいところですが、「Kotlin/Native」は、KotlinクラスからObjective-Cのクラスだったり、Objective-Cのプロトコルだったりします。
その際に変換が入っていて、単純なKotlinクラスではなくなってしまっているので、とても使いづらくなっています。
例えばですが、型でQualifireを作る時は引数がKClassになっています。DIコンテナからinstanceを取得する時には、KClassをkeyにしているので、KClassを指定してinstanceを引っ張ってきます。
Qualifireも同様に、KClassをQualifireに変換するというかたちなので、基本的にKClassが必要になってきます。
そのため、Objective-CのクラスやプロトコルをKotlinのクラスに変換できるkotlinx.cinterop関数が定義されています。getOriginalKotlinClassの引数は、ObjCClass、もしくはObjCProtocolの2種類です。
実際にどう使っていくのかですが、Multiplatform側に、今書いているような拡張関数を作成してみましょう。
ObjCClassを引数に受け取って、そこからKClassに変換して、Koinからinstanceを引っ張ってきて返す、もしくはプロトコルを受け取って、Kotlinクラスに変換して、Koinからinstanceを引っ張ってくるという拡張関数を定義します。
これはSwiftのコードですが、そうすることでKoinのinstanceからスッキリ呼び出せるようになりました。ただ、Force Castを毎回書かなければいけないというのは、少し冗長に感じます。
もう1個、Swift側で拡張関数を書きます。プロトコルの場合は上、クラスの場合は下ですね。簡単な拡張関数を作成すると、もっとスッキリ呼び出せるようになります。
コンテナから呼び出すほうはおしまいです。
Qualifireを作成するのも同様に、ObjCProtocol、もしくはObjCClassを引数にして、もとのKotlinクラスを変換して、それぞれTypeQualifireを作成する関数を書くと、スッキリ呼び出せるようになります。
メインのKoinの使い方の話はおしまいですが、よくある管理方法だと、Multiplatformのリポジトリが別管理になっていて、publishをしたけれど、DIの定義が間違っていてクラッシュすることがあります。それを直すためにもう1回直して、publishしてartifactを出さなきゃいけない、みたいなことがあると思うのですが、Koinは、Android側でModule定義のテストが書けます。
久保出さんの発表でもあったのですが、主要なモックのlibraryがKotlin/Nativeに対応していないので、JVMだけでテストできます。「koin-test-junit4」か「koin-test-jnit5」、「mockito」か「mockk」を組み合わせてテストを書けます。
テストは、KoinTestというインターフェイスがあるので、それを実装して、MockProviderRuleを当てはめる必要があります。
実際のテストですが、下のcheckModelesのDSLの中に、作成したModuleの定義を書いて、JUnitで実行させるだけです。
以上で発表はおしまいです。サンプルは「GitHub」のリポジトリに上げているので、ぜひ見てみてください。パッと動かせるようになっていると思うので、試してもらえればなと思います。
ご清聴ありがとうございました。
司会者:三好さんありがとうございます。1点、久保出さんから質問です。「Mobile.IOS、Mobile.ANDROIDは、KoinのAPIですか?」。これに関してはいかがでしょうか?
三好:いえ、単なるEnumの定義です。ちょっとわかりやすくなかったかもしれませんが、普通の単なるEnumです。
司会者:なるほど、ありがとうございます。
2024.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには