android - 使用来自多个模块 dagger 2.11 android 的依赖项

标签 android dependency-injection dagger-2 dagger

您好,我在我的项目的域包中有两个模块,并且有一个使用 DaggerAppComponent 手动注入(inject)自身的 firebase insance 服务类。

然后我在我提到的两个模块上有两个注入(inject)依赖项。

ModuleOne 有一个叫做 storage 的依赖,而 ModuleTwo 有一个叫做 delegator。

当尝试将这两个注入(inject)到我的 firebase 服务类中时,它提示无法从 ModuleTwo 定位和找到委托(delegate)注入(inject)器。

但是,如果我将委托(delegate)者的提供方法接口(interface)复制到 ModuleOne 中,它就可以正常工作(现在提示它多次绑定(bind),但可以通过添加命名约定轻松修复)。

这是一种我不喜欢做的 hacky 方式,只是希望能够使用来自不同模块的任何依赖项。这可能吗?

下面是我的 firebase 服务类

class MyInstanceIdService : FirebaseInstanceIdService() {

    @Inject
    lateinit var delegator: AccountDelegatorContract

    @Inject
    lateinit var Storage: StorageContract

 override fun onCreate() {
        super.onCreate()
        AndroidInjection.inject(this)
    }
    override fun onTokenRefresh() {
        DaggerApplicationComponent.builder().application(application as MyApplication).build().inject(this)
        val refreshToken = FirebaseInstanceId.getInstance().token

//        val pianoStorage: PianoStorage = PianoStorage(this)
        sendTokenToServer(refreshToken, storage.getUniqueId())
    }

    private fun sendTokenToServer(refreshToken: String?, uniqueId: String) {
        //TODO: Send this new token to server

        delegator.sendPushToken(PushTokenRequest(refreshToken!!, uniqueId))
    }

这里是 moduleOne,它代表主模块,它包含我的应用程序中多个域包中使用的依赖项。

@Module
abstract class MainModule {

 @ContributesAndroidInjector(modules = [AccountModule::class])
    @ViewScope
    abstract fun bindInstanceIdService(): MyInstanceIdService


      @Provides
        @Singleton
        @JvmStatic
        fun provideApplicationContext(application: Application): Context = application
 @Provides
        @Singleton
        @JvmStatic
        fun provideStorageData(storage: MainStorage): StorageContract = storage

}

这是特定于域包的 ModuleTwo

@Module
abstract class AccountModule {
     @Module
    companion object {
        @ViewScope
        @JvmStatic
        @Provides
        fun providesAccountDelegator(accountDelegate: AccountDelegator): AccountDelegatorContract = accountDelegate

        @ViewScope
        @JvmStatic
        @Provides
        fun providesAccountControllerContract(accountNetworkController: AccountNetworkController): AccountControllerContract = accountNetworkController

    }

}

我的应用程序组织在不同的包中,代表应用程序的一部分/域,例如帐户、用户、车辆、消息等,每个域都有自己的模块,用于定义与该域相关的特定依赖项。

我的问题是如何使用位于不同模块的上述依赖项?

编辑:我的 appCOmponent 看起来像这样

@Singleton
@Component(modules = arrayOf(MainModule::class,
AccountModule ::class))

interface ApplicationComponent : AndroidInjector<DaggerApplication> {
    fun inject(MyApplication: MyApplication)
    fun inject(myInsanceIdService: MyInstanceIdService)
    override fun inject(instance: DaggerApplication)

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

        fun build(): ApplicationComponent
    }
}

最佳答案

您将 AccountModule(使用 ViewScope sope 的提供方法)添加到您的 AppComponent 以及您的子组件(使用 @ContributesAndroidInjector bindInstanceIdService 声明),所以我想知道如何/为什么要编译。所以首先你应该从你的应用程序组件中删除 AccountModule,因为它有一个不同的范围,在那里对你没有任何好处。

其次,尽管 ApplicationComponent 不包含 inject(service : MyInstanceIdService) 方法。同样,我不明白这将如何/为什么编译。如上所述,您注册了一个子组件 (@ContributesAndroidInjector bindInstanceIdService) 来注入(inject)您的服务,因此您应该使用它。您的应用组件甚至没有提供所有对象的正确范围。

更糟糕的是,您在 MyInstanceIdService 中创建了另一个 AppComponent,所以即使这可行,您现在也有 2 个单例组件提供 2 “单例”对象的不同实例。不要在其范围之外重新创建组件。使用 MyApplication.getAppComponent() 并使用那个!

因此,在从 AppComponent 中删除 AccountModule 之后,您应该让您的应用程序实现 HasServiceInjector,像您在 Activity 中所做的那样注入(inject)/返回调度注入(inject)器。然后使用 AndroidInjection.inject(this) 注入(inject)您的服务。

总结:

  • 检查你的范围。 @Singleton 组件不能提供@ViewScope 东西。
  • 不要在组件上注册不同作用域的模块,它们无论如何都不能使用
  • 不要使用与您需要的范围不同的组件注入(inject)对象
  • 在创建子组件时不要重新创建组件。使用现有的!
  • 如果您使用 dagger.android 则不要自己创建组件,而是实现正确的接口(interface)并使用 AndroidInjection.inject()

关于android - 使用来自多个模块 dagger 2.11 android 的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49794391/

相关文章:

java - android更改选择器和选项卡下划线的默认颜色

android - 拉伸(stretch)图像以适应

android - 关于ionic框架和从服务器获取数据

java - 动态创建对象的依赖注入(inject)的好处

android - TextWatcher.afterTextChanged 在退格后有不正确的字符串

c# - 如何注入(inject) Web api IHttpRouteConstraint?

java - OpenJPA、 Jersey 、JUnit : Using a different persistence unit for my unit tests?

java - Dagger 2 ContributesAndroidInjector 为模块提供 Activity

android - Dagger 2 如何使用子组件将一个类注入(inject)多个组件?

design-patterns - 如何使用 dagger2 设置和获取模型类的 Singleton 对象?