2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術