簡體   English   中英

Hilt 遷移期間如何替換 DaggerAppComponent - Android 依賴注入

[英]How To Replace DaggerAppComponent During Hilt Migration - Android Dependency Injection

我正在將我們的應用程序從 Dagger 2 遷移到 Hilt。 我對所有這一切都很陌生,並且度過了一段非常艱難的時光。

BaseApplication ,我試圖替換當前使用 DaggerAppComponent 構建器構建的DaggerAppComponent

整個代碼庫中都有對AppComponent的引用,所以我不確定如何刪除/替換此功能。

基礎應用程序.kt

open class BaseApplication : Application() {
    
    ...

    lateinit var appComponent: AppComponent
        private set

    ...

    appComponent = DaggerAppComponent.builder()
            .appModule(AppModule(this))
            .build()

    appComponent.inject(this)
}

應用組件.kt

@Singleton
@Component(modules = [AppModule::class, NetworkService::class, AnalyticsModule::class])
interface AppComponent {

    fun providesNetworkService(): NetworkService

    fun inject(activity: MapActivity)
    fun inject(viewModel: NetworkBaseViewModel)
    fun inject(application: BaseApplication)
    fun inject(contactsDataSourceFactory: ContactsDataSourceFactory)
    fun inject(contactDetailViewModel: ContactDetailViewModel)
    fun inject(contactDetailFragment: ContactDetailFragment)
    fun inject(contactDetailEditFragment: ContactDetailEditFragment)
    fun inject(contactDetailCreateFragment: ContactDetailCreateFragment)
    fun inject(contactsListViewModel: ContactsListViewModel)
    fun inject(activityFeedViewModel: ActivityFeedViewModel)
    fun inject(httpService: BaseHttpService)
    fun inject(httpService: BaseWebService.ClientWrapper)
    fun inject(pdfViewerFragment: PDFViewerFragment)
    fun inject(commuteTimeManager: CommuteTimeManager)
    fun inject(verifyLoginWorker: VerifyLoginWorker)
    fun inject(loginWebFragment: LoginWebFragment)
}

這就是問題開始的地方。 我通過用@InstallIn(SingletonComponent::class)注釋它並用@Inject constructor()替換參數來更新 AppModule。 根據錯誤,模塊上的構造函數必須為空。

應用模塊.kt

@InstallIn(SingletonComponent::class) // <- Added
@Module
// class AppModule(private val application: BaseApplication) { // <-Removed
class AppModule @Inject constructor() { // <- Added

    // Old Code:
    // @Provides
    // @Singleton
    // fun provideApplication(): BaseApplication  = application

    // @Provides
    // @Singleton
    // internal fun provideContext(): Context = application

    // New Code:
    @Provides
    @Singleton
    fun provideApplication(@ApplicationContext application: BaseApplication): BaseApplication {
        return application as BaseApplication
    }

}

現在在DaggerAppComponent構建器中出現錯誤:

Too many arguments for public constructor AppModule() defined in com.companyname.db.dependencyinjection.AppModule

appComponent = DaggerAppComponent.builder()
                .appModule(AppModule(this)) // <- Here is the error
                .build()

如果我不能向AppModule添加構造函數,我應該如何解決這個問題?

**注意:我正在嘗試逐個遷移應用程序,因為這里有很多移動部件,這就是我沒有完全刪除AppComponent的原因。 也許我在那里缺少一些東西。 我一直在遵循遷移指南並嘗試添加/刪除聚合器入口點。

AppComponent NetworkBaseViewModel.kt 使用示例

open class NetworkBaseViewModel (application: Application): BaseViewModel(application) {

    ...

    init {
        @Suppress("LeakingThis")
        (application.applicationContext as? BaseApplication)?.appComponent?.inject(this@NetworkBaseViewModel)

    ...
}

使用 Hilt 時不必這樣做:

appComponent = DaggerAppComponent.builder()
    .appModule(AppModule(this))
    .build()

您所要做的就是使用 @HiltAndroidApp 注釋您的應用程序@HiltAndroidApp 由於您的 BaseApplication 是open ,我假設您必須在擴展它的 Application class 中執行此操作。

您也不必在 NetworkBaseViewModel 中執行此操作:

(application.applicationContext as? BaseApplication)?.appComponent?.inject(this@NetworkBaseViewModel)

現在您只需使用@HiltViewModel注釋您的 ViewModel 並且當您想將某些內容注入您的 ViewModel 時,您使用@Inject注釋構造函數並使其依賴項可注入(通過構造函數注入或使用Modules )。 例如:

@HiltViewModel
class NetworkViewModel @Inject constructor(
    private val retrofitService: ExampleRetrofitService
) : ViewModel() {

    // ViewModel stuff

}

此外,您的 AppModule 甚至不需要帶有@Inject注釋的構造函數,因為您沒有向其中注入任何東西。 請參閱此處的示例模塊,它只是一個object

最后,我推薦閱讀本指南 -> 使用 Hilt 進行依賴注入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM