Dagger 2错误:依赖项“如果没有@Provides注释的方法就无法提供”

时间:2018-11-28 09:32:03

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

我已经开始将Dagger 2与Android Injector结合使用并遇到问题

我有5个模块,它们组成一个组件

@Singleton
@Component(modules = [AndroidInjectionModule::class,
    ActivityBuilder::class,
    AndroidSupportInjectionModule::class
    , ApplicationModule::class,NetworkModule::class])

interface ApplicationComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): ApplicationComponent
    }
    fun inject(app: DeliveryApplication)
    fun service(): DeliveryApi

}

网络模块外观

@Module
class NetworkModule  {

    @Singleton
    @Provides
    fun providesDeliveryApi(retrofit: Retrofit):DeliveryApi = retrofit.create(DeliveryApi::class.java)

    @Singleton
    @Provides
    fun providesRetrofit(okHttpClient: OkHttpClient):Retrofit =
            Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(okHttpClient)
                    .build()


    @Singleton
    @Provides
    fun providesOkHttpClient(context:Context): OkHttpClient {
       /* val logging = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }*/
        val cacheSize = (5 * 1024 * 1024).toLong()
        val myCache = Cache(context.cacheDir, cacheSize)

        val okHttpClient = OkHttpClient.Builder()
                .cache(myCache)
                .addInterceptor { chain ->
                    var request = chain.request()
                    request = if (hasNetwork(context)!!)
                        // setting  5 Mb Cabacity
                        request.newBuilder().header("Cache-Control", "public, max-age=" + 5).build()
                    else
                        request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build()
                    chain.proceed(request)
                }
                .build()

        return okHttpClient
    }


    @Singleton
    @Provides
    fun provideImageLoader(context: Context) : ImageLoader {
        return PicassoImageLoader(Picasso.with(context))
    }

应用程序模块外观

const val SCHEDULER_MAIN_THREAD = "mainThread"
const val SCHEDULER_IO = "io"

@Module
class ApplicationModule {
    @Provides
    @Named(SCHEDULER_MAIN_THREAD)
    fun provideAndroidMainThreadScheduler() : Scheduler = AndroidSchedulers.mainThread()
    @Provides
    @Named(SCHEDULER_IO)
    fun provideIoScheduler() : Scheduler = Schedulers.io()

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

ActivityBuilder非常简单:只是Activity模块的组合    和FragmentsModule片段

@Module
abstract class ActivityBuilder {
    @PerActivity
    @ContributesAndroidInjector(modules = [FragmentsModule::class, DeliveriesModule::class])
    abstract fun bindMainActivity(): DeliveriesActivity

    @PerActivity
    @ContributesAndroidInjector(modules = [FragmentsModule::class, DeliveriesDetailsModule::class])
    abstract fun bindDeliveryDetailsActivity(): DeliveryDetailsActivity
}


@Module
 abstract class FragmentsModule {
    @ContributesAndroidInjector
    abstract fun provideDeliveriesListFragment(): DeliveriesListFragment
    @ContributesAndroidInjector
    abstract fun provideDeliveryDetailsFragment(): DeliveryDetailsFragment
}

用于提供DeliveryActivity所有实例的交付模块

@Module
class DeliveriesModule {


    @Provides
    @PerActivity
    fun providesDeliveryRepository(deliveryApi: DeliveryApi): DeliveryRepository {
        return  DeliveryDownloader(deliveryApi)
    }


    @Provides
    @PerActivity
    fun providesDeliveryListUseCases(deliveryRepository: DeliveryRepository): DeliveryListUseCase {
        return DeliveryListInteractor(deliveryRepository)
    }



    @Provides
    @PerActivity
    fun provideDeliveriesListFragment(): DeliveriesListFragment {
        return DeliveriesListFragment()
    }

}

ViewModelFactory出现问题的地方,编译器说没有@Provides批注的方法就无法提供DeliveryListUseCase

class ViewModelFactory @Inject constructor(private val application: Application,
                                           @Named(SCHEDULER_IO) val subscribeOnScheduler: Scheduler,
                                           @Named(SCHEDULER_MAIN_THREAD) val observeOnScheduler: Scheduler,
        private val deliveryListUseCase: DeliveryListUseCase) : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        return when {
            modelClass.isAssignableFrom(DeliveryListViewModel::class.java)  ->
                DeliveryListViewModel(application,deliveryListUseCase,subscribeOnScheduler,observeOnScheduler) as T
            else -> BaseViewModel(application) as T
        }
    }
}

1 个答案:

答案 0 :(得分:0)

似乎我已经弄清楚了什么地方错了

问题。作为DeliveriesActivity模块的DeliveriesModule,因此我必须为DeliveriesListFragment创建另一个模块并提供DeliveryListUseCase

@Blackbelt,谢谢你给我一个提示