Hel*_*oCW 0 dependency-injection kotlin dagger-hilt
我正在学习依赖注入,以下代码A和代码B来自项目https://github.com/android/sunflower
\n作者PlantDao在代码A中定义了依赖注入,但在代码B中手动PlantDao创建了一个对象。database.plantDao()
为什么作者不对PlantDao代码 B 中的对象使用依赖注入?如何对PlantDao代码 B 中的对象使用依赖注入?
代码A
\n@InstallIn(SingletonComponent::class)\n@Module\nclass DatabaseModule {\n\n @Singleton\n @Provides\n fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {\n return AppDatabase.getInstance(context)\n }\n\n @Provides\n fun providePlantDao(appDatabase: AppDatabase): PlantDao {\n return appDatabase.plantDao()\n }\n\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n代码B
\nclass SeedDatabaseWorker(\n context: Context,\n workerParams: WorkerParameters\n) : CoroutineWorker(context, workerParams) {\n override suspend fun doWork(): Result = withContext(Dispatchers.IO) {\n try {\n val filename = inputData.getString(KEY_FILENAME)\n if (filename != null) {\n applicationContext.assets.open(filename).use { inputStream ->\n JsonReader(inputStream.reader()).use { jsonReader ->\n ...\n val database = AppDatabase.getInstance(applicationContext)\n database.plantDao().insertAll(plantList)\n\n ...\n } else {\n ...\n }\n } catch (ex: Exception) {\n ...\n }\n }\n\n ..\n}\nRun Code Online (Sandbox Code Playgroud)\n新增内容
\n致安德鲁:谢谢!
\n在这个问题中,你告诉我这@InstallIn(SingletonComponent::class)将适用于整个应用程序,你可以看到图1。
作者PlantDao在代码A中定义了一个依赖注入对象,并将其安装为SingletonComponent::class.
所以我认为 的对象PlantDao将会对整个应用程序可用\xef\xbc\x8c为什么不能直接在代码 B 中使用 PlantDao 的依赖注入对象呢?
代码D
\nclass SeedDatabaseWorker @Inject constructor(\n database: AppDatabase,\n context: Context,\n workerParams: WorkerParameters\n) : CoroutineWorker(context, workerParams) {\n override suspend fun doWork(): Result = withContext(Dispatchers.IO) {\n try {\n val filename = inputData.getString(KEY_FILENAME)\n if (filename != null) {\n applicationContext.assets.open(filename).use { inputStream ->\n JsonReader(inputStream.reader()).use { jsonReader ->\n ... \n database.plantDao().insertAll(plantList)\n ...\n } else { \n ..\n }\nRun Code Online (Sandbox Code Playgroud)\n
您必须使用 注释您的工作线程@HiltWorker,使用 注释您的上下文和参数@Assisted,使用 注释您的构造函数@AssistedInject,然后您可以通过构造函数注入您的 dao。
@HiltWorker
class SeedDatabaseWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted workerParams: WorkerParameters,
private val database: AppDatabase
) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
try {
val filename = inputData.getString(KEY_FILENAME)
if (filename != null) {
applicationContext.assets.open(filename).use { inputStream ->
JsonReader(inputStream.reader()).use { jsonReader ->
...
database.plantDao().insertAll(plantList)
...
} else {
...
}
} catch (ex: Exception) {
...
}
}
..
}
Run Code Online (Sandbox Code Playgroud)
此外,您必须将默认的 WorkerFactory 更改为 hiltWorkerFactory 并删除默认的初始化程序:
@HiltAndroidApp
class ExampleApplication : Application(), Configuration.Provider {
@Inject lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
Run Code Online (Sandbox Code Playgroud)
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)
implementation 'androidx.hilt:hilt-work:1.0.0'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation 'androidx.work:work-runtime-ktx:2.5.0'
Run Code Online (Sandbox Code Playgroud)
请注意,稍后将 androidx.work 更新到 2.6 时,某些流程会发生变化。你可以在这里阅读更多
您可以直接在代码 b 中使用依赖注入 plantdao。这就是private val database: AppDatabase构造函数内部的含义。第一步,您提供了 plantdao 并告诉它如何创建 plantdao 实例。在下一步(代码 b)中,您通过构造函数注入来保留 plantdao 的实例。您必须首先将其提供给 hilt(通过模块),然后您可以保留它(通过构造函数注入)。
| 归档时间: |
|
| 查看次数: |
1700 次 |
| 最近记录: |