您好,我在我的项目的域包中有两个模块,并且有一个使用 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/