簡體   English   中英

具有多個依賴項的 Dagger2 組件

[英]Dagger2 component with more than one dependencies

這是我目前擁有的並且有效:

@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) 不能依賴於作用域的組件

我在這里找到了答案: 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);
}

您不能在依賴項數組中使用作用域組件(我不得不說這很奇怪),只能使用無作用域,或一個作用域 + 其他無作用域。 但是你可以用“代理”接口欺騙匕首:

@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

你想確定在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 {}

請注意,無作用域的提供者在每次注入調用時都會創建一個新實例。 如果您需要作用域,您應該將模塊綁定到同一個組件,但組件應該只依賴於具有子作用域的其他組件。

現在 Dagger 支持一個可以依賴於 1 個以上作用域依賴項的組件。 只需將您的匕首版本更新到 2.27

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

api 'com.google.dagger:dagger:2.27'
kapt 'com.google.dagger:dagger-compiler:2.27'

在你的模塊中包含這樣的依賴模塊:

@Module(includes = FacebookModule.class)
public class AnotherModule {...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM