当前位置: 首页 > 知识库问答 >
问题:

Dagger 2子组件注入错误

吕利
2023-03-14

我有两个组件:AppComponent和ApiComponent。我想在ApiComponent和注入了ApiComponent的对象中使用由AppComponent提供的依赖项。因此,我将ApiComponent视为AppComponent的子组件。我已经声明AppComponentApiComponent中的依赖项,使用依赖项指令:

@ApiScope
@Component(dependencies = { AppComponent.class},
           modules = { ApiModule.class })
public interface ApiComponent {
    void inject(Application application);
    void inject(IntentService1 service1);

    SampleApi sampleApi();
}

以下是我的AppComponent:

@Singleton
@Component (modules = { AppModule.class })
public interface AppComponent {
    void (Class2 class2);

    Bus bus();
    SharedPreferences sharedPreferences();
    SampleApplication sampleApplication(); 
}

我的API模块的相关部分如下所示:

@Module
public final class ApiModule {
    @Provides
    @ApiScope
    SampleApi provideSampleApi(Retrofit retrofit) {
        return retrofit.create(SampleApi.class);;
    }
}

我在IntentService 1的onCreate()方法中触发注入:

@Inject SampleApi sampleApi;

@Override
public void onCreate() {
    SampleApplication.get().getApiComponent().inject(this);
}

但我得到以下编译错误:

SampleApi不能在没有@Provides或@product注释方法的情况下提供

有人知道发生了什么吗?我感谢你的帮助。

共有2个答案

景子安
2023-03-14

我的问题是瞄准镜。我在声明范围时使用了不正确的注释。这就是我现在声明范围的方式:

@Retention(RetentionPolicy.RUNTIME)
@Scope
public @interface ApiScope {
}

令人恼火的是,依赖组件不能具有与其父组件相同的单例作用域,并且必须为所有单例组件声明命名作用域,但原因如下所述。另外,请确保模块中的所有提供程序方法都使用与组件作用域相同的作用域进行注释。以下是我的提供程序方法之一:

@Provides
@ApiScope
UserApi provideUserApi(Retrofit retrofit) {
    return retrofit.create(UserApi.class);
}

并确保通过在父组件(接口)和依赖组件中声明与它们提供的依赖项同名的方法(除了首字母大写),显式公开父组件的依赖项,如下所示:

Bus bus();
SharedPreferences sharedPreferences();
MyApplication myApplication();

还要确保公开(依赖)模块在(依赖)组件中提供的依赖项,同样,公开器方法的名称应与依赖项的名称相同,但第一个字母除外:

UserApi userApi();

也一定要看看这篇关于匕首2的非常有用和准确的文章。这个stackoverflow回答帮助我确定了关于声明作用域的问题,并管理了依赖的生命周期。

PS:我避免使用术语“子组件”,因为在Dagger 2中声明“子组件”有不同的方式,即使从属组件和子组件在概念上是相同的。

上官凯歌
2023-03-14

我也在处理这个案子。我相信您需要的是一个@子组件。我相信dependencies指令适用于您的较低级别模块(为了清楚起见,避免使用'sub'一词)不知道(或不想知道)您的'root'模块(即包含事件总线等项的模块)中声明的依赖项的情况。引用Dagger2关于组件依赖关系的文档={};

组件依赖

虽然子组件是组成绑定子图的最简单方法,但子组件与父组件紧密耦合;它们可以使用由其祖先组件和子组件定义的任何绑定。作为替代,组件可以通过声明组件依赖项仅使用来自另一个组件接口的绑定。当类型用作组件依赖项时,依赖项上的每个预配方法都被绑定为提供程序。请注意,只有作为预配方法公开的绑定可以通过组件依赖项获得。

我试图重写你的代码来帮助,但我不能说我理解这一切,所以我将向你展示我最近是如何在我的应用程序中使用这个构造的。希望这能有所帮助,你能把你的案子和这个相提并论。

所以

场景:我的SplashActiveLocalBroadcastManager依赖和活动Context贡献到根模块的图中,并使用主模块提供的数据库依赖...非常类似于您的用例。

@PerActivity
@Subcomponent(
    modules = SplashActivityModule.class
)
public interface SplashActivityComponent {
  void inject(final SplashActivity splashActivity);
}

片段1: Splash活动子组件

@Module
public class SplashActivityModule {
  private final Context activity;

  /**
   * Constructs the activity module.
   *
   * @param activity The activity context.
   */
  public SplashActivityModule(final Activity activity) {
    this.activity = activity;
  }


  /**
   * Provide the (domain) context.
   *
   * @return The context of the domain module.
   */
  @Provides
  @PerActivity
  Context provideContext() {
    return activity;
  }


  /**
   * Provide the local broadcast manager.
   *
   * @return the broadcast manager.
   */
  @Provides
  @PerActivity
  LocalBroadcastManager provideLocalBroadcastManager() {
    return LocalBroadcastManager.getInstance(activity);
  }
}

片段2:活动(又名SplashActivityModule)的注入说明

@Component(modules = DomainModule.class)
public interface DomainComponent {
  SplashActivityComponent plus(final SplashActivityModule splashActivityModule);
}

代码片段3:提供图形入口点的父(或根)模块。

@Override
protected void setupActivityComponent(final DomainComponent domainComponent) {
  domainComponent.plus(new SplashActivityModule(this)).inject(this);
}

代码片段4:SplashActivity执行注入的代码(在onCreate的超级调用之后立即调用)

希望有帮助。请将您的发现与此保持联系,因为我正在努力解决子模块无法了解父模块的情况。。。i、 e.不是@子组件

 类似资料:
  • 我的应用程序中有以下Dagger2架构: 其中:AppComponent: UserComponent: ActivityComponent: ChatComponent: 首先,如何将不同的注入到类中?要么是应用程序,要么是活动?? 其次,我在编译代码时遇到了一个奇怪的问题,错误是: 错误:(23,10)错误:br.com.animaeducacao.ulife.domain.interacto

  • 我刚开始使用Dagger并尝试使用dagger2进行DI,但看起来它给我的活动注入了一个空演示器。下面是我的代码。 公共类TasksActivity扩展AppCompatActivity{

  • 在添加com.google.dagger:dagger-android-support依赖项后,我得到了这个gradle错误。 这是我的构建的一部分

  • 本文向大家介绍Dagger2 Android依赖注入学习笔记,包括了Dagger2 Android依赖注入学习笔记的使用技巧和注意事项,需要的朋友参考一下 前言 最近在用 MVP + RxJava + Retrofit 写项目,觉得相对于其他的开发框架,这的确是给我们带来了很多方便,但是在网上搜寻相关资料的时候,总是能看到 MVP + RxJava + Retrofit + Dagger 这样的搭

  • 我有一个ionic 2应用程序,我一直在使用本地数据进行测试。现在,我正试图向我的api发出一些Ajax请求以获取数据。 在我的文件,我正在这样定义我的组件: 然后,我的文件的定义如下: 然后,最后,我用我的文件初始化我的注册视图: 我预期的结果是,在初始化我的注册视图时,将注入。因此,它的构造函数将运行,这将触发构造函数中的函数。然后,我应该在浏览器网络选项卡中看到一个网络调用。 但是,我得到了

  • 我试图将一组房间组件注入存储库,存储库本身使用Dagger2注入ViewModel(在片段中)。 代码如下。 片段: 视图模型: 我的存储库: 最后,对于我的匕首类,我有两个模块: 和我的AppComponent: Dagger编译正常,我可以访问并构建它。但是是不可访问的(检查类将其显示为私有),我需要实际注入依赖项的方法也是如此。结果我得到错误: 我该如何解决这个问题?