Dagger 2:避免导出私有依赖项

Dagger 2: avoid exporting private dependencies

假设我有一个模块,我只想导出 A 的一个实例。但是,此 A 需要在构造函数中传递 BC 的实例。所以我们也会在模块中声明它们:

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(); 
    }
}

这有效,但现在 BC 也可以在代码的其他地方使用。我想将它们保密并强制客户端 类 只能访问 A.

有办法实现吗?

实现该目标的最简单方法是使用 @Qualifier 绑定您不希望可用的类型(在本例中为 BC)那是不可访问的。

然后,虽然 BC 可能可以从模块外部访问,但为了注入它们,您需要提供限定符,但事实并非如此。

@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(); 
  }
}

一个简单的方法是

@Retention(BINARY)
@Qualifier
private annotation class InternalApi

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

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

here.

中剔除

基本上,我们创建私有限定符 - 在本例中,@InternalApi 用于限定 OkHttpClient 依赖项,从而使其对我们的模块私有。