【问题标题】:@Component.Builder is missing setters for required modules or components [Dagger2]@Component.Builder 缺少所需模块或组件的设置器 [Dagger2]
【发布时间】:2018-05-29 16:00:50
【问题描述】:

我正在尝试使用 Component.Builder 来注入我的模块,但 RestModule 有问题 - 我的模块之一。 它返回

错误:(41, 5) 错误:@Component.Builder 缺少 setter 所需的模块或组件: [com.injection.module.services.RestModule]

这是 ApplicationComponent

@Singleton
@Component(modules = {PresenterEnvironmentModule.class,
    RestModule.class})
public interface PresenterEnvironmentComponent {


@Component.Builder
interface Builder {

    @BindsInstance
    Builder sharedPreferenceService(SharedPrefService sharedPreferences);

    @BindsInstance
    Builder loggingService(LoggingService loggingService);

    @BindsInstance
    Builder applicationService(Application application);

    @BindsInstance
    Builder connectivityService(ConnectivityService connectivityService);

    @BindsInstance
    Builder schedulersService(SchedulersService schedulersService);

    @BindsInstance
    Builder sessionService(SessionService sessionService);



    PresenterEnvironmentComponent build();

}

@NonNull
PresenterEnvironment presenterEnvironment();

void inject(BaseBootstrapActivity<BaseBootstrapPresenter> baseBootstrapActivity);
}

这是 RestModule:

 @Module
 public class RestModule {
 private final boolean debuggable;
 private final String baseUrl;
 @NonNull
 private final TokenInterceptor tokenInterceptor;
 @NonNull
 private final BootstrapRestService bootstrapRestService;
 @Nullable
 private Interceptor[] additionalInterceptors;
 @Nullable
 private Function<OkHttpClient.Builder, OkHttpClient.Builder> onOkHttpClient;
@Nullable
private Function<OkHttpClient.Builder, OkHttpClient.Builder> onOkHttpClientForUploading;

public RestModule(@NonNull RestSettings restSettings) {
    this.debuggable = restSettings.isDebuggable();
    this.baseUrl =  restSettings.getBaseUrl();
    this.tokenInterceptor =   restSettings.getTokenInterceptor();
    this.bootstrapRestService = restSettings.getRestService();
    this.onOkHttpClient = restSettings.getOnOkHttpClient();
    this.onOkHttpClientForUploading = restSettings.getOnOkHttpClientForUploading();
    this.additionalInterceptors =     restSettings.getAdditionalInterceptors();
}

@Provides
@Singleton
@NonNull
@Type.Basic
public OkHttpClient provideOkHttpClient(@NonNull TokenInterceptor tokenInterceptor,
                                        @NonNull HttpLoggingInterceptor loggingInterceptor,
                                        @NonNull OkLogInterceptor okLogInterceptor,
                                        @NonNull CachingInterceptor cacheInterceptor) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(tokenInterceptor);
    if (additionalInterceptors != null && additionalInterceptors.length > 0) {
        for (Interceptor interceptor : additionalInterceptors) {
            builder.addInterceptor(interceptor);
        }
    }
    if (onOkHttpClient != null) {
        builder = apply(onOkHttpClient, builder);
    }
    if (debuggable) {
        // Add HttpLoggingInterceptor
        builder.addInterceptor(loggingInterceptor);
        // add cache interceptor
        builder.addNetworkInterceptor(cacheInterceptor);
        // add okLog interceptor
        builder.addInterceptor(okLogInterceptor);
    }
    return builder.build();
}

@Provides
@Singleton
@NonNull
@Type.ForUploading
public OkHttpClient provideOkHttpClientForUploading(@NonNull TokenInterceptor tokenInterceptor,
                                                    @NonNull HttpLoggingInterceptor loggingInterceptor,
                                                    @NonNull OkLogInterceptor okLogInterceptor,
                                                    @NonNull CachingInterceptor cacheInterceptor) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(tokenInterceptor);

    if (additionalInterceptors != null && additionalInterceptors.length > 0) {
        for (Interceptor interceptor : additionalInterceptors) {
            builder.addInterceptor(interceptor);
        }
    }

    if (onOkHttpClientForUploading == null) {
        builder.writeTimeout(60, TimeUnit.SECONDS);
        builder.connectTimeout(60, TimeUnit.SECONDS);
        builder.readTimeout(60, TimeUnit.SECONDS);
    } else {
        builder = apply(onOkHttpClientForUploading, builder);
    }
    if (debuggable) {
        // Add HttpLoggingInterceptor
        builder.addInterceptor(loggingInterceptor);
        // add cache interceptor
        builder.addNetworkInterceptor(cacheInterceptor);
        // add okLog interceptor
        builder.addInterceptor(okLogInterceptor);
    }
    return builder.build();
}

@Provides
@Singleton
@NonNull
public OkLogInterceptor provideOkLogInterceptor() {
    return new OkLogInterceptor.Builder().withAllLogData().build();
}

@Provides
@Singleton
@NonNull
public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    return interceptor;
}

@Provides
@Singleton
@NonNull
@Type.Basic
public Retrofit provideRetrofit(@NonNull @Type.Basic OkHttpClient client) {
    return new Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(client)
            .addConverterFactory(LoganSquareConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
}

@Provides
@Singleton
@NonNull
@Type.ForUploading
public Retrofit provideRetrofitForUploading(@NonNull @Type.ForUploading OkHttpClient client) {
    return new Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(client)
            .addConverterFactory(LoganSquareConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
}

@Provides
@Singleton
@NonNull
public CachingInterceptor provideCachingInterceptor(LoggingService loggingService) {
    return new CachingInterceptor(loggingService);
}

@Provides
@Singleton
@NonNull
public TokenInterceptor provideTokenInterceptor() {
    return tokenInterceptor;
}

@Provides
@Singleton
@NonNull
public BootstrapRestService provideBaseRestService(@NonNull @Type.Basic Retrofit retrofit,
                                                   @NonNull @Type.ForUploading Retrofit retrofitForUploading) {
    return bootstrapRestService.setup(retrofit, retrofitForUploading);
}


@NonNull
private <T, R> R apply(@NonNull Function<T, R> f, @NonNull T t) {
    try {
        return Preconditions.checkNotNull(f.apply(t));
    } catch (Throwable ex) {
        throw new IllegalStateException("Applying function for " + t.toString() + " Threw " + ex);
    }
}



 }

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:
    @Module
    public class RestModule {
      // ...
      public RestModule(@NonNull RestSettings restSettings) {
    

    RestModule 是一个可实例化的模块,没有可见的无参数构造函数。 Dagger 不知道如何创建它的实例。您需要在 @Component.Builder 上提供类似 Builder restModule(RestModule restModule) 的方法,并在创建过程中像 @BindsInstance 方法一样调用它。

    Dagger 无法实例化自身的每个模块依赖项(例如,模块没有可见的无参数构造函数)必须有一个抽象的 setter 方法。其他模块依赖项(Dagger 可以实例化的)是允许的,但不是必需的。 (来自@Component.Builder javadoc


    并非所有模块都是可实例化的;有些是接口或抽象类。因为 Dagger 静态调用静态方法,并在编译时对 @Binds 方法进行反射,所以很多模块根本不需要实例化。这通常更优化,因为 Dagger 可以跳过创建实例。

    对于可实例化但具有可见的零参数构造函数的模块,Dagger 可以自动调用new,您可以将这些模块从构建器中移除。 (您可以选择包含它们;它们不需要被调用,但如果您将模块子类化,它们可能会很有用,which the docs advise against anyway。)

    对于可实例化但只有带参数的构造函数的模块,Dagger 无法创建模块;它不会像 @Provides 方法那样为构造函数提供图中的参数。您需要显式创建一个 Builder 方法,并使用您自己创建的 Module 实例调用它。

    【讨论】:

    猜你喜欢
    • 2017-10-20
    • 2020-09-02
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    相关资源
    最近更新 更多