Kotlin - dagger 2
Dependencies
Project build.gradle
buildscript {
ext.dagger_version = '2.5'
}
App build.gradle
apply plugin: 'kotlin-kapt'
dependencies {
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
}
下面我們直接來看一個範例:
我這邊使用四個Model,分別為Model A B C D
ModelA 裡面包含了 B跟C
ModelC 裡面包含了 D
class ModelA @Inject constructor(val context: Context, var modelB: ModelB, var modelC: ModelC){
var somethingData: String = "modelA haha "
fun print() {
Log.d("ModelA", somethingData + modelB.somethingData + modelC.somethingData)
}
}
傳入的context,實際上沒用到只是純粹練習print() 會印出ModelA的data,data會將ABC的data加起來
ModelB:
class ModelB @Inject constructor(){
var somethingData: String = "modelB haha "
}
ModelC:
class ModelC @Inject constructor(modelD: ModelD){
var somethingData: String = "modelC haha " + modelD.somethingData
}
ModelC包含ModelDModelD:
class ModelD @Inject constructor(){
var somethingData: String = "modelD haha "
}
AppModule:
@Module
class AppModule @Inject constructor(private val context: Context) {
@Provides
fun provideModelA(modelB: ModelB, modelC: ModelC): ModelA {
Log.d("AppModule", "provideModelA")
return ModelA(this.context, modelB, modelC)
}
@Provides
fun provideModelB() = ModelB()
// @Provides
// fun provideModelB(): ModelB {
// Log.d("ModelB", "provided")
// return ModelB()
// }
@Provides
fun provideModelC(modelD: ModelD): ModelC {
return ModelC(modelD)
}
@Provides
fun provideApplicationContext(): Context = context
}
AppComponent
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
fun inject(myApplication: MainActivity)
}
實際使用:
class MainActivity : AppCompatActivity() {
@Inject
lateinit var modelA: ModelA
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerAppComponent.builder()
.appModule(AppModule(this))
.build()
.inject(this)//必须注入一下
tv1.setOnClickListener { rx1() }
}
private fun rx1() {
Log.d("DaggerAppComponent", "data" + modelA.print())
}
}
Inject
在Dagger2中, @Inject 可以用來標記建構子、屬性、以及函式,這裡以標記建構子作為範例。
- 生產實例的工廠,每個一個實例都是通過@Provides修飾的方法提供的
- 專門解決,不是自己寫的類別無法在其構造函數上加@Inject的情況
- 當然自己寫的類別也可以通過@Provides修飾的方法提供,這樣就不會找@Inject的構造函數了
component 是一個橋樑,是一個接口
- 一個conponent可以組織多個模塊,一個conponent還可以組織引入其他的組件
- 依賴的查找順序為:先找@module,如果找到了就停止,如果找不到就去找@Inject
留言
張貼留言