Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 593
Mister Smith Avatar asked Apr 07 '17 07:04

Mister Smith


2 Answers

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(); 
  }
}
like image 198
gk5885 Avatar answered Sep 21 '22 15:09

gk5885


A simple way to do this is

@Retention(BINARY)
@Qualifier
private annotation class InternalApi

@Module
object NetworkModule {
  @Provides 
  @InternalApi 
  fun provideClient(): OkHttpClient {
    //...
  }

  @Provides
  fun provideRetrofit(
    @InternalApi client: Lazy<OkHttpClient>
  ): Retrofit {
    //...
  }
}

culled from here.

Basically, we create private qualifiers- in this case, @InternalApi that is used to qualify the OkHttpClient dependency thus making it private to our module.

like image 40
Shayne3000 Avatar answered Sep 21 '22 15:09

Shayne3000