如何修复dagger2库中的“没有@Provides注释方法就无法提供”错误

时间:2019-10-24 08:00:26

标签: java android kotlin dependency-injection dagger-2

代码

我刚刚开始学习dagger2并在实现以下模块时遇到问题。

AppComponent:

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

fun inject(app: App)

@Component.Builder
interface Builder {

    @BindsInstance
    fun application(application: Application): Builder

    fun build(): AppComponent
}
}

应用程序:

class App : Application(), HasAndroidInjector {

  @Inject
  lateinit var androidInjector: DispatchingAndroidInjector<Any>

  override fun androidInjector() = androidInjector

  override fun onCreate() {
    super.onCreate()
    initDagger()
  }

  private fun initDagger() {
    DaggerAppComponent.builder()
        .application(this)
        .build()
        .inject(this)
  }
}

AppModule:

@Module
class AppModule {

  @Provides
  @Singleton
  fun provideContext(application: Application): Context {
    return application
  }

  @Provides
  @ApiInfo
  fun provideApiKey(): String {
    return "mApiKey"
  }

  @Provides
  @Singleton
  fun providePreferencesHelper(appPreferencesHelper: AppPreferencesHelper): PreferencesHelper {
    return appPreferencesHelper
  }

  @Provides
  fun provideSchedulerProvider(): SchedulerProvider {
    return AppSchedulerProvider()
  }
 }

DataManager

interface DataManager : PreferencesHelper {

    enum class LoggedInMode constructor(type: Int) {

    LOGGED_IN_MODE_LOGGED_OUT(0),
    LOGGED_IN_MODE_GOOGLE(1),
    LOGGED_IN_MODE_FB(2),
    LOGGED_IN_MODE_SERVER(3);

    private var mType: Int = type

    fun getType(): Int {
        return mType
    }
   }
 }

ActivityBuilder:

@Module
abstract class ActivityBuilder {

  @ContributesAndroidInjector
  abstract fun bindSplashActivity(): SplashActivity 
}

ViewModelProviderFactory:

 @Singleton
 class ViewModelProviderFactory @Inject
 constructor(
 private val dataManager: DataManager,
 private val schedulerProvider: SchedulerProvider
 ) : ViewModelProvider.NewInstanceFactory() {

     override fun <T : ViewModel> create(modelClass: Class<T>): T {
    if (modelClass.isAssignableFrom(SplashViewModel::class.java)) {
        return SplashViewModel(dataManager, schedulerProvider) as T
    }
    throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name)
   }
 }

错误

我从此实现中得到的错误是...

错误:如果没有@Provides注释的方法,则无法提供[Dagger / MissingBinding] com.example.package.data.DataManager。

 public abstract interface AppComponent {
            ^
  com.example.package.data.DataManager is injected at
      com.example.package.ViewModelProviderFactory(dataManager, …)
  com.example.package.ViewModelProviderFactory is injected at
      com.example.package.ui.splash.SplashActivity.factory
  com.example.package.ui.splash.SplashActivity is injected at
      dagger.android.AndroidInjector.inject(T) [com.example.package.di.component.AppComponent ? com.example.package.di.builder.ActivityBuilder_BindSplashActivity.SplashActivitySubcomponent]

1 个答案:

答案 0 :(得分:0)

Dagger无法注入接口。也不能。

我看到DataManager是一个接口。如果要注入它的实现,则假设我们将该实现称为:DataManagerImpl。

      @Provides
      fun provideDataManager (): DataManager {
        return DataManagerImpl()
      }

否则,您的代码就没有意义。我的意思是这里:

@Singleton
 class ViewModelProviderFactory @Inject
 constructor(
 private val dataManager: DataManager, <<<<------ HERE?!
 private val schedulerProvider: SchedulerProvider
 ) : ViewModelProvider.NewInstanceFactory() {