Lets say I have a module where I only want to export an instance of A
. However this A
requires instances of B
and 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?
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();
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With