Home > Software design >  Conflicting `@Inject`
Conflicting `@Inject`

Time:08-19

a recent hilt update added some warnings and I'm a bit lost on what their trying to tell me and the link in the warning isn't very helpful either.

warning: [Dagger/DuplicateBindings] com.demo.myapp.data.repositories.datastores.AppSettingsRepository is bound multiple times:

@Inject com.demo.myapp.data.repositories.datastores.AppSettingsRepository(com.demo.myapp.data.datastores.CompanySettingsDataStore) [com.demo.myapp.App_HiltComponents.SingletonC]

@Provides @dagger.hilt.android.scopes.ViewModelScoped @org.jetbrains.annotations.NotNull com.demo.myapp.data.repositories.datastores.AppSettingsRepository com.demo.myapp.di.modules.RepositoryModule.provideAppSettingsRepository(com.demo.myapp.data.datastores.CompanySettingsDataStore) [com.demo.myapp.App_HiltComponents.SingletonC ? com.demo.myapp.App_HiltComponents.ActivityRetainedC ? com.demo.myapp.App_HiltComponents.ViewModelC]

This condition was never validated before, and will soon be an error. See https://dagger.dev/conflicting-inject.

I'm hoping someone can better explain the warning, because I don't know what it thinks is duplicated.

CodePudding user response:

The error says that AppSettingsRepository is bound twice: once in SingletonComponent and once in ViewModelComponent.

The SingletonComponent binding comes from an @Inject annotation on AppSettingsRepository. There is something provided in SingletonComponent that depends (directly or indirectly) on AppSettingsRepository, so Dagger automatically puts that binding in SingletonComponent.

The ViewModelComponent binding comes from an explicit @Provides method in RepositoryModule, which is installed in ViewModelComponent.

As mentioned in the linked page, you have three options:

  • Remove the ViewModelScoped binding. AppSettingsRepository sounds like it should be a singleton anyway, so you can always annotate the class with @Singleton if it's important for all bindings in the same ViewModel to use the same instance.

  • Move the ViewModelScoped binding to SingletonComponent. The only dependency of your @Provides method is already available in SingletonComponent, so this is certainly possible in this case.

  • Put a qualifier on the ViewModelScoped binding. This is appropriate if the @Provides method has additional logic beyond simply calling the constructor, and this logic is not wanted in SingletonComponent. In that case, you will want to make anything else in ViewModelComponent that depends on AppSettingsRepository uses a qualifier for this dependency.


Note that SingletonC in the error output is a Dagger component generated by Hilt, corresponding to Hilt's SingletonComponent. The same applies to ViewModelC, which is a Dagger subcomponent corresponding to ViewModelComponent. The warning was generated by Dagger (not Hilt) while trying to process these components.

  • Related