Android Örnekleri #2 - Dependency Injection - Koin Kütüphanesi Kullanımı - #2
Android dependency injection - Koin kütüphanesi kullanımı - 2
Koin kullanımı serisi ilk yazısına buradan ulaşabilirsiniz.
Koin kütüphanesi kullanımı serisinin 2. bölümü ile devam ediyoruz.
Bu yazıda Koin'i; viewmodel entegrasyonu, Koin module unit testi gibi konular ile detaylandıracağız.
Öncelikle app build.gradle dosyasına Koin kütüphanesini ekliyoruz.
dependencies { def koinVersion = "2.1.5" implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.0' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' // Koin implementation "org.koin:koin-android:$koinVersion" implementation "org.koin:koin-androidx-scope:$koinVersion" implementation "org.koin:koin-androidx-viewmodel:$koinVersion" implementation "org.koin:koin-androidx-fragment:$koinVersion" testImplementation "org.koin:koin-test:$koinVersion" }
MainViewModel class'ını oluşturalım.
class MainViewModel : ViewModel() { val helloText = "Hello Koin" }
Şimdi di package'ı altına mainModule kotlin file'ı oluşturalım. Bu dosyada MainActivity'i çalıştırmak için gerekli objeleri oluşturacağız. (MainViewModel gibi)
di.MainModule:
import com.emreakcadag.koinexample.MainViewModel import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module /** * Created by Emre Akçadağ on 16.06.2020 */ val mainModule = module { // Bu şekilde isimlendirilmiş instance'lar da oluşturabiliyoruz. single(named("APP_NAME")) { "Koin Example" } // ViewModel sınıfları viewModel scope'u içinde tanımlıyoruz. viewModel { MainViewModel() } }
MainViewModel'i viewModel scope'u içinde yarattık. bu kullanım sadece viewModel sınıfları için geçerlidir.
MyApplication class'ı son hali:
class MyApplication: Application() { override fun onCreate() { super.onCreate() startKoin { // Debug level'da loglaması için Level.DEBUG parametresi geçtik. androidLogger(Level.DEBUG) androidContext(this@MyApplication) // buraya farklı paketler için de (networkModule vs) oluşturduğunuz modulleri eklemeniz gerek. modules(listOf(mainModule)) } } }
MyApplication sınıfını AndroidManifest.xml'de application tag'ine name attribute olarak vermek gerekiyor. Yoksa koin başlayamayacağı için uygulama kendini kill eder.
... android:name=".MyApplication" ...
Şimdi viewModel'i activity'de inject edebiliriz. MainActivity:
class MainActivity : AppCompatActivity() { private val mainViewModel: MainViewModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) runOnUiThread { // Bu örnek için optional. textView.text = mainViewModel.helloText } } }
MainActivity içinde by viewModel() ile MainViewModel'i inject ettik.
Artık normal obje -MainViewModel()- oluşturmuş gibi kullanabiliriz.
Koin Unit Test
MainModuleTest sınıfını KoinTest sınıfından extend edip, @Test fonksiyonlarını aşağıdaki gibi yazıyoruz.
import com.emreakcadag.koinexample.di.mainModule import junit.framework.Assert.assertNotNull import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Before import org.junit.Test import org.koin.core.context.startKoin import org.koin.core.context.stopKoin import org.koin.core.qualifier.named import org.koin.test.KoinTest import org.koin.test.get import org.koin.test.inject /** * Created by Emre Akçadağ on 16.06.2020 */ class MainModuleTest : KoinTest { private val appName: String by lazy { get<String>(named("APP_NAME")) } // Test için inject kullandık. private val mainViewModel: MainViewModel by inject() // Class çalıştığında ilk gireceği fonksiyon @Before fun setup() { startKoin { modules(listOf(mainModule)) } } // Class çalıştığında son gireceği fonksiyon @After fun koinStop() { stopKoin() } @Test fun `Test APP_NAME Created`() { assertTrue(appName == "Koin Example") } @Test fun `Test MainViewModel Created`() { assertNotNull(mainViewModel) } }
Yazının sonuna gelirken; Koin kütüphanesi orta ve küçük ölçekli uygulamalar için uygun ancak daha büyük projeler için kullanılmasını pek tavsiye etmiyorum.
Büyük projeler için Dagger2 veya Google'in yeni Dependency Injection kütüphanesi Hilt çok daha sağlıklı olacaktır.
İlerleyen günlerde yeni bir seri ile Hilt kütüphanesini örneklendirmeye çalışırım :)
Kaynak kod: github.com/emreakcadag/koin-example
Sorularınızı ve isteklerinizi yorum bölümünden iletebilirsiniz.Kaynak: