Dagger 2-不兼容范围绑定

问题描述 投票:0回答:1

我正在尝试为我的学习项目使用Dagger 2创建基本架构,但是遇到了一些问题……

当前的错误匕首告诉我

FeedMeApplicationComponent.java:7: error: [Dagger/IncompatiblyScopedBindings] .FeedMeApplicationComponent (unscoped) may not reference scoped bindings:

当我将ActivityMainModule添加为应用程序的模块时,我只有这个问题

和ActivityMainModule包含仅与MainActivity相关的子组件。

我不明白为什么我不能将此子组件模块添加到应用程序图中:令人困惑

这些是我的Dagger类...

class FeedMeApplication : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerFeedMeApplicationComponent.factory().create(this)
    }
}
@Component(modules = [AndroidInjectionModule::class, NetworkModule::class, NutritionModule::class, ActivityMainModule::class])
interface FeedMeApplicationComponent : AndroidInjector<FeedMeApplication> {

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance context: Context): FeedMeApplicationComponent
    }

    override fun inject(instance: FeedMeApplication?)
}
@Module
object NetworkModule {

    @Singleton
    @Provides
    @JvmStatic
    fun provideNutritionService(retrofit: Retrofit): NutritionService {
        return retrofit.create(NutritionService::class.java)
    }

    @Singleton
    @Provides
    @JvmStatic
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create())
            .baseUrl("https://api.edamam.com/api")
            .client(okHttpClient)
            .build()
    }

    @Singleton
    @Provides
    @JvmStatic
    fun provideOkHttp(): OkHttpClient {
        return OkHttpClient()
            .newBuilder()
            .addInterceptor(ApiInterceptor())
            .build()
    }

    private class ApiInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request().newBuilder()
            request
                .addHeader("api_id", “abc")
                .addHeader("app_key", “123")
            return chain.proceed(request.build())
        }
    }
}
@Module
object NutritionModule {

    @Singleton
    @Provides
    @JvmStatic
    fun provideNutritionRepository(nutritionService: NutritionService): NutritionRepository {
        return NutritionRepository(nutritionService)
    }
}
@Module(subcomponents = [MainActivityComponent::class], includes = [MainModule::class])
abstract class ActivityMainModule {
    @Binds
    @IntoMap
    @ClassKey(MainActivity::class)
    abstract fun bindAndroidInjector(factory: MainActivityComponent.Factory): AndroidInjector.Factory<*>
}

@Module
object MainModule {

    @Singleton
    @Provides
    @JvmStatic
    fun provideMainViewModelFactory(nutritionRepository: NutritionRepository): MainViewModel.Factory {
        return MainViewModel.Factory(nutritionRepository)
    }

    @Provides
    @JvmStatic
    fun provideMainViewModel(
        viewModelFactory: MainViewModel.Factory,
        fragmentActivity: FragmentActivity
    ): MainViewModel {
        return ViewModelProviders.of(fragmentActivity, viewModelFactory)
            .get(MainViewModel::class.java)
    }
}
@ActivityScope
@Subcomponent
interface MainActivityComponent : AndroidInjector<MainActivity> {

    @Subcomponent.Factory
    interface Factory : AndroidInjector.Factory<MainActivity> {}
}
class MainActivity : DaggerAppCompatActivity() {

    @Inject
    lateinit var mainViewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mainViewModel.liveDataFoodAnalysis.observe(this, Observer { food ->
            Log.d("Food answer", food.uri)
        })
        mainViewModel.getFoodAnalysisResponse("egg")
    }
}

android kotlin dependency-injection dagger-2 dagger
1个回答
0
投票

您必须将annotate设置为FeedMeApplicationComponent @Singleton。因为NetworkModuleNutritionModule都定义了@Provides范围内的@Singleton函数,所以使用这些模块的任何组件也必须将其自己的范围指定为@Singleton

来自Dagger docs:-

由于Dagger 2将图形中的作用域实例与实例相关联组件实现,组件本身需要声明他们打算代表的范围。例如,它不会具有@Singleton绑定和@RequestScoped毫无意义绑定在同一组件中,因为这些作用域具有不同生命周期,因此必须生活在具有不同生命周期的组件中。要声明某个组件与给定范围相关联,只需将范围注释应用于组件接口。

© www.soinside.com 2019 - 2024. All rights reserved.