gpt4 book ai didi

android - Dagger 2 通过 Modules 与 Inject 构造函数进行配置

转载 作者:行者123 更新时间:2023-12-02 13:19:27 24 4
gpt4 key购买 nike

我正在尝试将 dagger-android 添加到 Kotlin 项目中,并且在需要创建模块以及仅声明 Inject 构造函数时感到困惑。

假设有以下依赖图:

Activity
-> ViewModel
-> Repository
-> Webservice
-> Dao
-> Database
-> Application

提供 ViewModel对于 Activity我们为 Activity 和 ViewModel 工厂创建各自的模块,然后在 Activity 中手动创建 ViewModel,如下所示:
@Module
abstract class ActivityModule {
@ContributesAndroidInjector
abstract fun mainActivity(): MainActivity
}

// Skiping ViewModelKey and ViewModelFactory code for brevity
@Module
abstract class ViewModelModule {
@Binds
internal abstract fun bindViewModelFactory(
factory: ViewModelFactory
): ViewModelProvider.Factory

@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
internal abstract fun mainViewModel(viewModel: MainViewModel): ViewModel
}

class MainActivity : DaggerAppCompatActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewModel: MainViewModel

override fun onCreate(savedInstanceState: Bundle?) {
...
viewModel = ViewModelProviders.of(this, viewModelFactory)
.get(HomeViewModel::class.java)
}
}

提供 Repository对于 ViewModel我们只是声明 @Inject constructor像这样:
class MainViewModel @Inject constructor(private val repository: Repository): ViewModel() {}

提供 WebserviceDao对于 Repository以及 Database对于 Dao,我们创建了相应的模块,如下所示:
@Module
class NetworkModule {
@Provides
@Singleton
fun provideWebservice() = Webservice.create()
}

interface Webservice {
...
companion object Factory {
fun create(): Webservice {
...
return retrofit
}
}
}


@Module
class DataModule {
@Provides
@Singleton
fun provideApplicationDatabase(app: Application) =
AppDatabase.getDatabase(app)

@Provides
@Singleton
fun provideUserDao(db: AppDatabase) = db.userDao()
}

@Database(...)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao

companion object {
fun getDatabase(context: Context): AppDatabase {
...
return instance
}
}
}

ApplicationDabatabase 提供通过 AppComponent 和 Application 类中的一些魔法
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
NetworkModule::class,
DataModule::class,
ViewModelModule::class,
ActivityModule::class
])
interface AppComponent: AndroidInjector<App> {
@Component.Builder
interface Builder {
@BindsInstance
fun create(application: Application): Builder
fun build(): AppComponent
}
}

class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> =
DaggerAppComponent.builder().create(this).build()
}

问题是 :
  • 数据库如何获取应用程序实例?是 AndroidSupportInjectionModule 有魔法吗?
  • 为什么我们需要为 Web 服务和数据库创建模块而不是存储库?
    是否可以注释 Webservice 接口(interface)和 Database 类本身以跳过为它们创建单独的 dagger 模块?
  • 最佳答案

    问题一数据库如何获取应用程序实例?是 AndroidSupportInjectionModule 有魔法吗?

    答:不,这不是 AndroidSupportInjectionModule 的工作。 AndroidSupportInjectionModule 包含在 Dagger Android Support 中,它有助于

    “配置绑定(bind)以确保 dagger.android 和 dagger.android.support 框架类的可用性。” Found Here

    所以,基本上你只是在创建 Dagger Builder 时传递应用程序上下文,你现在只需从应用程序类传递它一旦你在主组件中得到它,你的所有模块中都有应用程序上下文,我们在初始化房间数据库时需要上下文.

    问题2 为什么我们需要为 Web 服务和数据库创建模块而不是存储库?是否可以注释 Webservice 接口(interface)和 Database 类本身以跳过为它们创建单独的 dagger 模块?

    答:
    首先,总是尽量实现构造函数注入(inject)。 Modules 的总体思路是“如果我们不拥有这个类,我们就不能 @annotate 它的构造函数,所以我们制作 Modules 来提供它们的实现”。如果我们想注入(inject)接口(interface),我们可以通过它的构造函数注入(inject)通过它的实现类来实现它。
    所以我们不拥有 WebService 和数据库的初始化,这就是我们创建它们的模块并提供它们的原因,以便我们可以在我们的存储库中获取它们的实例。我们拥有我们的存储库类,因此我们可以通过构造函数注入(inject)来注入(inject)它们。

    关于android - Dagger 2 通过 Modules 与 Inject 构造函数进行配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59843328/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com