12

这是我目前拥有的,并且有效:

@FragmentScope
@Component(dependencies = {FacebookComponent.class}, 
           modules = {FragmentFacebookLoginModule.class})
public interface FragmentFacebookLoginComponent {

    void inject(FragmentFacebookLogin fragment);
}

现在我想添加另一个依赖项。我把它改成这样:

@Component(dependencies = {FacebookComponent.class, AnotherComponent.class}, 
           modules = {FragmentFacebookLoginModule.class})

但现在我收到此错误消息:

FragmentFacebookLoginComponent 依赖于多个作用域组件

我该如何解决这个问题?我怎样才能拥有多个依赖项?

如果我从一个组件中删除范围,我会收到以下错误消息:

AnotherComponent (unscoped) 不能依赖于作用域组件

4

5 回答 5

4

我在这里找到了答案:https ://stackoverflow.com/a/29619594/1016472

最后,我创建了一个具有正确范围的 AppComponent,并让 FacebookComponent 和 AnotherComponent 扩展了这个 AppComponent。

FacebookComponent 和 AnotherComponent 没有它自己的范围(我删除了它)。

现在看起来像这样:

@AppScope
@Component
public interface AppComponent {

}


@Component(modules = {FacebookModule.class})
public interface FacebookComponent extends AppComponent {

}


@Component(modules = {AnotherModule.class})
public interface AnotherComponent extends AppComponent {

}


@FragmentScope
@Component(dependencies = {FacebookComponent.class, AnotherComponent.class}, 
           modules = {FragmentFacebookLoginModule.class})
public interface FragmentFacebookLoginComponent {

    void inject(FragmentFacebookLogin fragment);
}
于 2015-05-24T15:52:15.957 回答
3

您不能在依赖项数组中使用作用域组件(我不得不说这很奇怪),只能使用非作用域,或者一个作用域 + 另一个未作用域。但是你可以用“代理”接口欺骗匕首:

@Component
@Singleton
interface ComponentA {
    fun provideSomeA()
}

interface ProxyComponentA : ComponentA

@Component
@Singleton
interface ComponentB {
    fun provideSomeB()
}

interface ProxyComponentB : ComponentB

@Component(dependencies = [ProxyComponentA::class, ProxyComponentB::class])
@OtherScope
interface ComponentC

但是在您的 ComponentC 构建器中,您应该使用代理组件实现,这可以通过 Kotlin 轻松实现:

class ProxyComponentAImpl(private val delegate: ComponentA) : ProxyComponentA, ComponentA by delegate
class ProxyComponentBImpl(private val delegate: ComponentB) : ProxyComponentB, ComponentB by delegate

componentA = DaggerComponentA.builder()...
componentB = DaggerComponentB.builder()...

componentC = DaggerComponentC.builder()
                   .componentA(ProxyComponentAImpl(componentA))
                   .componentB(ProxyComponentBImpl(componentB))

适用于 dagger 2.13 版本,其他不知道

您也可以反之使用继承 ComponentA : ProxyComponentA 来消除创建 ProxyComponentAImpl 的需要,但如果您的 ComponentA 位于例如不同的 gradle 模块中,这不是一个好的设计选择

该解决方案的灵感来自该问题讨论: https ://github.com/google/dagger/issues/1225

于 2018-09-14T15:34:27.147 回答
2

你要确定在的范围内,ApplicationScope应该都是没有范围定义的,只在ApplicationComponent给定范围下的应用范围内链接在一起。

例如,

@Component(modules = {FacebookModule.class})
public interface FacebookComponent {
    FacebookThing facebookThing(); //assuming this is with @Provides in FacebookModule with NO SCOPE
}


@Component(modules = {AnotherModule.class})
public interface AnotherComponent{
    AnotherThing anotherThing(); //assuming this is with @Provides in AnotherModule with NO SCOPE
}

然后你可以做

@AppScope
@Component(dependencies={AnotherComponent.class, FacebookComponent.class})
public interface AppComponent extends AnotherComponent, FacebookComponent {}

之后你可以做

@FragmentScope
@Component(dependencies=AppComponent.class)
public interface FragmentComponent extends AppComponent {}

请注意,无范围的提供程序会在每次注入调用时创建一个新实例。如果需要作用域,则应将模块绑定到同一个组件,但组件应仅依赖于其他组件以进行子作用域。

于 2015-05-26T21:33:37.287 回答
1

现在 Dagger 支持一个可以依赖多个作用域依赖的组件。只需将您的匕首版本更新到 2.27

https://github.com/google/dagger/issues/1414

api 'com.google.dagger:dagger:2.27'
kapt 'com.google.dagger:dagger-compiler:2.27'
于 2020-04-01T02:07:29.923 回答
0

在你的模块中包含这样的依赖模块:

@Module(includes = FacebookModule.class)
public class AnotherModule {...
于 2016-12-20T15:55:31.757 回答