Search code examples
javaandroiddependency-injectiondagger-2dagger

Dagger 2: avoid exporting private dependencies


Lets say I have a module where I only want to export an instance of A. However this A requires instances of Band C to be passed in the constructor. So we would declare them as well in the module:

public class SampleModule {

    @Provides
    @Singleton
    A provideA(B b, C c){
        return new A(b, c);
    }

    @Provides
    @Singleton
    B provideB(){
        return new B();
    }

    @Provides
    @Singleton
    C provideC(){
        return new C(); 
    }
}

This works, but now B and C are also available elsewhere in the code. I want to keep them private and force client classes to only have access to A.

Is there a way to achieve this?


Solution

  • The easiest way to accomplish that goal is to bind the types that you don't want to be made available (in this case B and C) with a @Qualifier that is not accessible.

    Then, while B and C might be be accessible from outside the module, in order to inject them you would need to supply a qualifier, which is not.

    @Module
    public final class SampleModule {
      @Qualifier
      @Retention(RUNTIME)
      private @interface SampleModuleOnly {}
    
      @Provides
      @Singleton
      static A provideA(@SampleModuleOnly B b, @SampleModuleOnly C c){
        return new A(b, c);
      }
    
      @Provides
      @SampleModuleOnly 
      @Singleton
      static B provideB(){
        return new B();
      }
    
      @Provides
      @SampleModuleOnly 
      @Singleton
      static C provideC(){
        return new C(); 
      }
    }