Dagger 2的子组件和具有依赖组件的组件出现问题



我正在开发Dagger 2,遇到了一个依赖注入问题。我会给你一个关于这个问题的想法。我有一个ApplicationComponent,如下所示。

@Singleton
@Component(modules = {AppModule.class, MySubComponent.class})
public interface ApplicationComponent {
   void inject(Application app);
   List<Integer> pattern;
   MySubComponent subcomponent();
}

正如您所看到的,我在上面的组件中定义了一个子组件。

ApplicationComponent comp = DaggerApplicationComponent.builder()
                .appModule(new ApplicationModule())
                .mySubModule(new MySubModule())
                .build();

这就是我创建应用程序组件实例的方式。

这是的子组件

@Singleton
@Subcomponent(modules = MySubModule.class)
public interface MySubComponent {
   void inject(AClass obj);
   INeedThis ineedthis(); 
}
@Module
public class MySubComponent {
   @Provides
   @Singleton
   INeedThis provideINeedThis() {
      return new INeedThis();
   }
}

然后我创建了另一个组件,LoginComponent,ApplicationComponent作为依赖

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity{}
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class)
public interface LoginComponent {
    void inject(FirstActivity activity);
}

我创建了LoginComponent实例,如下所示。

LoginComponent comp = DaggerLoginComponent.builder().loginModule(new LoginModule().applicationComponent(appComponentObject).build(); 

当我在FirstActivity中注入INeedThis对象时,就会出现这个问题。我的假设是,由于LoginComponent有ApplicationComponent的依赖项,ApplicationComponent有一个子组件MySubComponent,INeedThis对象应该被注入。但事实上,它没有做到这一点,我得到了以下错误。

INeedThis cannot be provided without an @Provides- or @Produces- annotated methods.

我读了很多关于dagger2的子组件的帖子。然而,它们并没有像预期的那样工作。我缺什么了吗?

首先,您在上面的代码中没有使用子组件,这个问题与它们无关,但这是另一个问题。

您的LoginComponent依赖于以下声明的ApplicationComponent

@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class)
public interface LoginComponent {}

这意味着使用LoginComponent可以注入LoginComponent所知道的一切。这就是LoginModule提供的一切,可以通过构造函数注入*创建的可能对象,以及ApplicationComponent公开的对象。

INeedThis不能在没有@Providers或@Produces注释方法的情况下提供。

这意味着,对于INeedThis来说,这些都不是真的。

@Component(modules = {AppModule.class, MySubComponent.class})

我不知道您是如何/为什么添加组件作为模块的。如果这是一个拼写错误,并且您将MySubModule添加到组件中,则只需将以下内容添加到exposeINeedThis:

@Component(modules = {AppModule.class, MySubModule.class})
public interface ApplicationComponent {
    //...
    INeedThis getINeedThis();
}

如果这不是打字错误,并且您实际上想要使用子组件,那么LoginComponent应该取决于实际的子组件,但一旦您将代码修复为实际使用子组件时,它也会以相同的方式工作。

考虑到您上面的子组件定义,您可以更改应用程序组件,使其不将组件列为模块,并添加一个方法来扩展您的ApplicationComponent:

@Singleton
@Component(modules = {AppModule.class}) // removed from modules
public interface ApplicationComponent {
   void inject(Application app);
   List<Integer> pattern;
   MySubComponent subcomponent(); // this will create your subcomponent
   // same as above
   // MySubComponent subcomponent(MySubModule module); use this if you also need to setup your module
}

然后你可以创建你的子组件,如下所示:

AppComponent appComponent = DaggerAppcomponent.create();
MySubComponent subComponent = appComponent.subcomponent(); // call the method  on your app component

然后,如果您按照以下方式更改LoginComponent

@Component(dependencies = MySubComponent.class, modules = LoginModule.class)
public interface LoginComponent { /**/ }

然后你可以像一样创建它

DaggerLoginComponent.builder().loginModule(new LoginModule().mySubComponent(subComponent).build();

和上面一样,您必须向MySubComponent接口添加一个getINeedThis(),以将对象暴露到子图中。

最新更新