2021년 5월 7일 금요일

Kotlin Koin

Kotlin Koin

Koin

Di (Dependense Injection) するためにはDagger2, HiltがあるがKotlinらしくなくて使い方がやや口説くなることがあったのでIntelliJ社はKotlin専用のDIライブラリのKoinを作った。
KoinはKotlinらしく使いやすい、簡単なのでDIなんかを初めて触った素人も即座で使える。

https://insert-koin.io/

早速やって見よう。

  1. build.gradle(Project: xxx) に追加
// Add Maven Central to your repositories if needed
repositories {
  mavenCentral()
}
dependencies {
  // Koin for Android
  compile "org.koin:koin-android:$koin_version"  
 // Testing
 testCompile "org.koin:koin-test:$koin_version"
}
  1. build.gradle(Module: xxx) に追加 (必要なものだけに加減する)
  
def koin_version = "2.1.5"  
  
// For Android  
// Koin for Android  
implementation "org.koin:koin-android:$koin_version"  
// Koin Android Scope features  
implementation "org.koin:koin-android-scope:$koin_version"  
// Koin Android ViewModel features  
implementation "org.koin:koin-android-viewmodel:$koin_version"  
// Koin Android Experimental features  
implementation "org.koin:koin-android-ext:$koin_version"    
testImplementation "org.koin:koin-test:$koin_version"
  
  
// For AndroidX  
// Koin AndroidX Scope features  
implementation "org.koin:koin-androidx-scope:$koin_version"  
// Koin AndroidX ViewModel features  
implementation "org.koin:koin-androidx-viewmodel:$koin_version"  
// Koin AndroidX Fragment features  
implementation "org.koin:koin-androidx-fragment:$koin_version"  
// Koin AndroidX Experimental features  
implementation "org.koin:koin-androidx-ext:$koin_version"
  1. 必要なモジュールを先に作る。
    Entity->Domain(Usecase, Repository) ->Module順。
    今回の例はちょっと違和感があるな。。
//-----------------------//
// package name/domain/entity/Article.kt
//-----------------------//
data class Article(  
    var say : String = "",  
)

//-----------------------//
// package name/domain/usecase/MyUseCase.kt
//-----------------------//
class MyUseCase (  
   private val localRepository: LocalRepository  
)  {  
    fun sayHelloMessageShowUseCase() : String {  
        return localRepository.getHelloMsg()  
    }  
}

//-----------------------//
// package name/domain/repository/LocalRepository.kt
//-----------------------//  
class LocalRepository(  
    private val databaseModule: DatabaseModule  
)  
{  
    fun getHelloMsg() = databaseModule.getDashboard().say  
}

//-----------------------//
// package name/di/DatabaseModule/DatabaseModule.kt
//-----------------------//  
class DatabaseModule(  
    val article: Article  
) {  
    fun getDashboard() : Article {  
        article.say = "Say Hello Koin"  
  return article  
  }  
}
  1. Application ファイルを作ってstartKoinをする。
    本当にシンプルすぎる。
class App : Application() {  
    override fun onCreate() {  
        super.onCreate()  
        startKoin {  
  androidContext(this@App)  
            modules(module {  
  factory { Article() }  
  single { DatabaseModule(get()) }  
  single { LocalRepository(get()) }  
  factory { DashboardUsecase(get()) }    
  viewModel { DashboardViewModel() }
 })  
        }  
  }  
}
  1. ViewModelで使う。KoinでViewModel用のモジュールを使うにはviewModelというキーワードを使わなきゃならないので注意。(viewModel { someClass() } )

普通はのInjectしたいとことにKoinComponentを継承すればできるはず。

//-----------------------//
// package name/ui/dashboard/DashboardViewModel.kt
//-----------------------//  
class DashboardViewModel : ViewModel(), KoinComponent {    
     private val usecase: sayHelloMessageShowUseCase by inject()    
    private val _text = MutableLiveData<String>().apply {  
  value = "This is dash Fragment"  
  }  
  val text: LiveData<String> = _text    
  fun change() {  
        _text.postValue(usecase.changeText())  
    }  
}

//-----------------------//
// package name/ui/dashboard/DashboardFragment.kt
//-----------------------//    
class DashboardFragment : Fragment(), KoinComponent {  
 val dashboardViewModel: DashboardViewModel by viewModel()
       
lateinit var textView: TextView  
override fun onCreateView(  
    inflater: LayoutInflater,  
    container: ViewGroup?,  
    savedInstanceState: Bundle?  
): View? {  
    val root = inflater.inflate(R.layout.fragment_dashboard, container, false)  
    textView = root.findViewById(R.id.text_dashboard)  
    dashboardViewModel.text.observe(viewLifecycleOwner, Observer {  
  textView.text = it  
 })  
    textView.setOnClickListener {  
  dashboardViewModel.change()  
    }  
  return root  
}
  1. TestCodeはこうやる
class SampleKoinTest : KoinTest {  
  
    private val usecase: DashboardUsecase by inject<DashboardUsecase>()  
  
    @get:Rule  
  val koinTestRule = KoinTestRule.create {  
  modules(AppModules().modules)  
    }  
  
  
  @Test  
  fun sampleTest() {  
        assert("Say Hello Koin" == usecase.changeText())  
    }  
}
  1. 終わり。アプリを走ってみるとDIがキチンと動く。

これは。。これは。。素晴らしいすぎる。
どんどんIntellJ社に支配されている感じがする。怖っ。。

KoinはLight weight DI ライブラリーなのでDaggerより多少の機能が足りないかもしれないがこれて十分だ。

Related Posts:

  • [日本語-漢字] 兼任 [日本語-漢字] 兼任 Sugoi Ebooks(Writen in English) Naver Cafe Sugoi Japanese Find a Job in Japan [日本語-漢字] 兼任 [日本語-漢字] 兼任 :けんにん 겸임 A_LIFE~愛しき人~#05-825-桜坂中央病院の外科部長として A_LIFE~愛しき人~#05:826:… Read More
  • [日本語-漢字] 健全 [日本語-漢字] 健全 Sugoi Ebooks(Writen in English) Naver Cafe Sugoi Japanese Find a Job in Japan [日本語-漢字] 健全 [日本語-漢字] 健全 :けんぜん 건전 13の理由.S01E06.JA-464-また映画の話ね 13の理由.S01E06.JA:465:不健全なバイト… Read More
  • [日本語-漢字] 健闘 [日本語-漢字] 健闘 Sugoi Ebooks(Writen in English) Naver Cafe Sugoi Japanese Find a Job in Japan [日本語-漢字] 健闘 [日本語-漢字] 健闘 :けんとう 건투 A.I.C.O. Incarnation.S01E03.JA-231-君たちになら 必ず成し遂げられる A.I… Read More
  • [日本語-漢字] 兼業 [日本語-漢字] 兼業 Sugoi Ebooks(Writen in English) Naver Cafe Sugoi Japanese Find a Job in Japan [日本語-漢字] 兼業 [日本語-漢字] 兼業 :けんぎょう 겸업 BOSS2nd#05-110-(花形)片柳 沙織さん 40歳。→ BOSS2nd#05:111:兼業主婦で … Read More
  • [日本語-漢字] 健忘症 [日本語-漢字] 健忘症 Sugoi Ebooks(Writen in English) Naver Cafe Sugoi Japanese Find a Job in Japan [日本語-漢字] 健忘症 [日本語-漢字] 健忘症 :けんぼうしょう 건망증 Dr.DMAT#09-493-硬膜下血腫の疑いがあります Dr.DMAT#09:494:外傷性健… Read More

0 comments:

댓글 쓰기