Dagger2 component with more than one dependencies

后端 未结 5 1314
轻奢々
轻奢々 2021-01-04 09:24

This is what I currently have and it works:

@FragmentScope
@Component(dependencies = {FacebookComponent.class}, 
            


        
相关标签:
5条回答
  • 2021-01-04 09:54

    Include on your module the dependency module like this:

    @Module(includes = FacebookModule.class)
    public class AnotherModule {...
    
    0 讨论(0)
  • 2021-01-04 09:59

    What you want to be determined to be within the ApplicationScope should be all defined without a scope, and linked together under the application scope only in the ApplicationComponent under the given scope.

    For example,

    @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
    }
    

    Then you can do

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

    After which you can do

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

    Please note that unscoped providers create a new instance on every inject call. If you need the scoping, you should bind the modules to the same component, but components should only depend on other components with the intention of subscoping.

    0 讨论(0)
  • 2021-01-04 10:07

    Now Dagger supports a component that can depends on more than 1 scoped dependencies. Just update your dagger version to 2.27

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

    api 'com.google.dagger:dagger:2.27'
    kapt 'com.google.dagger:dagger-compiler:2.27'
    
    0 讨论(0)
  • 2021-01-04 10:10

    I found the answer here: https://stackoverflow.com/a/29619594/1016472

    At the end I created a AppComponent with the right scope and let FacebookComponent and AnotherComponent extends this AppComponent.

    FacebookComponent and AnotherComponent does not have it's own scope (I removed it).

    Looks now like this:

    @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);
    }
    
    0 讨论(0)
  • 2021-01-04 10:10

    You can't use scoped components in a dependencies array (which is quite strange I have to say), only unscoped, or one scoped + other unscoped. But you can deceive dagger with "proxy" interfaces:

    @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
    

    But in your ComponentC builder you should use proxy components implementations, which could easily be achieved with 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))
    

    Works on dagger version 2.13, don't know about others

    Also you could use vice versa inheritance ComponentA : ProxyComponentA to eliminate the need to create ProxyComponentAImpl, but it's not a good design choice if your ComponentA lays for example in a different gradle module

    The solution was inspired by that issue discussion: https://github.com/google/dagger/issues/1225

    0 讨论(0)
提交回复
热议问题