Koinから環境変数を利用する
こんにちは、普段はAndroidでKotlinを書いている人間です。 この記事は Kotlin Advent Calendar 2019 13日目の記事です。
最近、Kotlinサーバサイドにチャレンジをしているのですがその際に、環境変数の扱いをどうするのが良いのかと言うことについて考えていましたが、 Koinと言うDIコンテナの機能を利用すると便利にできそうだなと思ったので、Koinの紹介を軽くしてから、そのTipsを共有したいと思います。 なお、本記事執筆の際に利用した環境は以下の通りです。
- Kotlin: 1.3.60
- Koin: 2.0.1
まずKoinについて
KoinはKotlinで書かれた軽量でシンプルなDIコンテナです。 導入に関しては、ドキュメントをみていただくのが最適だと思うので、ドキュメントへのリンクを案内させていただきます。
Koinはそのままでももちろん、AndroidやKtorとも連携してシンプルにDIを行うことができます。
環境変数を出力するアプリケーションを作ってみる
今回は、環境変数をprintln
する小さなアプリケーションを作りながら解説します。
環境変数にはMESSAGE
が設定されており、値にはHello, World!
と書かれています。
この環境変数を出力するアプリケーションを作っていきます。
まずはKoinを使わずにやる
通常の方法でやった場合がこちらです。
fun main() { println(System.getenv("MESSAGE")) }
はい、これ表示できました。ではKoinを使ってこれを置き換えていきましょう。
Koinを使う方法
環境変数を格納するクラスを用意します。今回はConfig
と言うクラスにします。
data class Config(val message: String)
このクラスをInjectすることで、環境変数のDIを実現していきます。
次に、このクラスをmodule
に追加します。
val module = module { single { Config(getProperty("MESSAGE")) } }
ここのsingle
ブロック内のthis
はScope
と呼ばれるクラスです。
このScope
には
fun <T> getProperty(key: String, defaultValue: T): T
fun <T> getProperty(key: String): T
fun <T> getPropertyOrNull(key: String): T?
と言う3つの関数が用意されており、このkey
に環境変数の名前を指定してあげることで取得できる仕組みとなっています。
getProperty
の内部実装は、PropertyRegistry
へのデリゲートとなっています。PropertyRegistry
へどのようにして環境変数が格納されるかについては後述します。
次に、このConfig
を利用するクラスを作ります。
class MainComponent : KoinComponent { private val config by inject<Config>() fun sayMessage() { println(config.message) } }
あとはこのmodule
をKoinの初期化時に渡します。
ここで忘れてはいけないのが、environmentProperties
の呼び出しです。
ここで呼び出さないと環境変数はKoinのpropertyRegistry
に登録されません。
environmentProperties
の中では、System.getProperties()
とSystem.getenv()
を呼び出し、そこで取得した値をPropertyRegistry
の中に保持します。
このenvironmentProperties
の動きを少しみてみます。
この関数はKoinApplication
クラスに実装されている関数で、内部でKoin
のPropertyRegistry
へ接続し、PropertyRegistry
のloadEnvironmentProperties
へと処理をデリゲートしています。
KoinApplication#environmentProperties()
→ Koin#getPropertyRegistry()
→ PropertyRegistry#loadEnvironmentProperties()
と言う流れです。
より内部の詳細が気になる方はこちらをご覧ください。
fun main() {
startKoin {
environmentProperties()
modules(listOf(module))
}
MainComponent().sayMessage()
}
MainComponent
のsayMessage
を実行するとめでたくHello, World!
と表示されると思います。
これで環境変数バンドルするクラスをInjectすることができるようになりました。
また、Koinは環境変数だけではなく、Propertiesファイルの読み込みもサポートしています。
その読み込みに関しても、先程の、getProperty
関数でサポートしているため、環境変数とPropertiesファイルの両方を統一的に扱うことができるのもKoinの良いところです。
終わりに
短かったですが、Koinでの環境変数の利用の方法を共有させていただきました。 それでは。