【问题标题】:Objects cannot be provided without an @Provides-annotated method没有@Provides-annotated 方法就不能提供对象
【发布时间】:2017-02-27 06:53:18
【问题描述】:

我已经开始设置 Dagger 2,遇到了一个奇怪的问题,对我来说似乎是一个错误。

我有 1 个主要组件和 1 个子组件,我在父组件中“加号”。

我用:

compile "com.google.dagger:dagger:2.4"
apt "com.google.dagger:dagger-compiler:2.4"
annotationProcessor "com.google.dagger:dagger-compiler:2.4"

应用程序组件非常简单。它只是“加”了子组件:

@Singleton @Component(modules = { AristocratsAppModule.class })
public interface AristocratsAppComponent {
  StreamComponent plus(StreamModule module);
}

应用模块也很基础。它提供了应用级别的依赖:

@Module public class AristocratsAppModule {
  private static AristocratsApp app;

  public AristocratsAppModule(AristocratsApp app) {
    AristocratsAppModule.app = app;
  }

  @Provides @Singleton AristocratsApp providesApplication() {
    return app;
  }

  @Provides @Singleton GsonXml providesGsonXml() {
    return ...
  }

  @Provides @Singleton @Named("aristocrats") Retrofit providesAristocratsRetrofit() {
    return ...
  }

  @Provides @Singleton @Named("last_fm") Retrofit providesLastFmRetrofit() {
    return ...
  }
}

子组件有两个 StreamServices(改造服务)和简单注入:

@PerController @Subcomponent(modules = { StreamModule.class }) public interface StreamComponent {
  void inject(StreamsController streamsController);

  AristocratsStreamService providesAristocratsStreamService();

  LastFmStreamService providesLastFmStreamService();
}

子组件的模块提供presenter注入和两种不同的Retrofit服务注入:

@Module public class StreamModule {
  private StreamsController mView;

  public StreamModule(StreamsController view) {
    mView = view;
  }

  @Provides @PerController StreamMvp.Presenter providesPresenter(StreamCase streamCase,
      StreamModelMapper streamMapper) {
    return new StreamPresenter(mView, streamCase, streamMapper);
  }

  @Provides @PerController AristocratsStreamService providesAristocratsStreamService(
      @Named("aristocrats") Retrofit retrofit) {
    return retrofit.create(AristocratsStreamService.class);
  }

  @Provides @PerController LastFmStreamService providesLastFmStreamService(
      @Named("last_fm") Retrofit retrofit) {
    return retrofit.create(LastFmStreamService.class);
  }
}

我在应用程序类的 onCreate() 中调用的应用程序注入:

mAppComponent = DaggerAristocratsAppComponent.builder()
        .aristocratsAppModule(new AristocratsAppModule(this))
        .build();

查看我在控制器中调用的注入:

getAppComponent().plus(new StreamModule(this)).inject(this);

我在构建期间遇到的异常:

Error:(13, 8) error: [com.qsoft.streams.presentation.di.StreamComponent.inject(com.qsoft.streams.presentation.StreamsController)] com.qsoft.streams.data.network.AristocratsStreamService cannot be provided without an @Provides-annotated method.
com.qsoft.streams.data.network.AristocratsStreamService is injected at
com.qsoft.streams.data.network.StreamApi.<init>(…, streamServiceAristocrats, …)
com.qsoft.streams.data.network.StreamApi is injected at
com.qsoft.streams.data.repository.StreamRepository.<init>(streamApi, …)
com.qsoft.streams.data.repository.StreamRepository is injected at
com.qsoft.streams.domain.interactors.StreamCase.<init>(streamRepository)
com.qsoft.streams.domain.interactors.StreamCase is injected at
com.qsoft.streams.presentation.di.StreamModule.providesPresenter(streamCase, …)
com.qsoft.streams.presentation.StreamMvp.Presenter is injected at
com.qsoft.streams.presentation.StreamsController.mPresenter
com.qsoft.streams.presentation.StreamsController is injected at
com.qsoft.streams.presentation.di.StreamComponent.inject(streamsController)
A binding with matching key exists in component: com.qsoft.streams.presentation.di.StreamComponent

关于缺少@Provides-annotated method 的错误投诉,但它们在我的子模块中。似乎 Dagger2 只是没有看到它们。我在想问题可能出在子组件中缺少AristocratsStreamService 的声明,所以我什至在其中添加了它,但没有任何改变。

这种情况看起来很奇怪,我想听听更有经验的 Dagger2 开发人员的一些意见。

提前谢谢你!

【问题讨论】:

    标签: android dependency-injection retrofit2 dagger-2 inject


    【解决方案1】:

    我注意到您没有在 AristrocratsModule 中设置子组件部分。

    这个:

    @Module public class AristocratsAppModule {
    

    进入这个:

    @Module(subcomponents = {StreamComponent.class})
    public class AristocratsAppModule {
    

    尝试进行以下更改。在您的 StreamComponent 中创建一个 Builder。

    @Subcomponent.Builder
    interface Builder {
        Builder streamModule(StreamModule module);
    
        StreamComponent build();
    }
    

    最终,您将通过 StreamComponent 注入所有内容,它也将在 AristocratsAppComponent 中注入所有内容。

    public StreamComponent getStreamComponent(Controller controller) {
        return getAppComponent().streamBuilder().streamModule(new StreamModule(controller)).build();
    }
    

    在此之后可以删除另外的东西。

    【讨论】:

    • 我试过了,但错误是一样的。它没有删除它。
    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多