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

时间:2016-05-04 14:22:05

标签: android 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的依赖关系,它具有子组件MySubComponent,因此应该注入INeedThis对象。但实际上,它没有这样做,我得到以下错误。

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

我在匕首2上阅读了很多关于子组件的帖子。但是,他们并没有像预期的那样工作。我有什么遗失的吗?

1 个答案:

答案 0 :(得分:3)

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

ApplicationComponent 取决于@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class) public interface LoginComponent {} 上的,如下所述:

LoginComponent

这意味着使用LoginComponent你可以注入LoginModule知道的所有内容。这是ApplicationComponent提供的所有内容,可以通过INeedThis中的构造函数注入*和公开对象创建的可能对象。

  

INeed如果没有@ Provide-或@ Produces-注释方法,则无法提供。

这说明,@Component(modules = {AppModule.class, MySubComponent.class}) 没有一个是真的。

MySubModule

我不知道如何/为何将组件添加为模块。如果这是拼写错误,并且您向组件添加INeedThis,则只需将以下内容添加到公开 @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();

然后您可以像

一样创建它
getINeedThis()

与上述相同,您必须在MySubComponent界面添加log_user 1 spawn ssh -o "StrictHostKeyChecking=no" $username@$hostname expect { ..... user and password checks ..... send "IF EXIST C:\\path\\to\\file\\temp.zip (echo FOUND) else (echo NOTFOUND)\r" expect "path" { set result $expect_out(buffer) puts $result if{$result=="FOUND"} { #compare with temp2.zip here } } 对象展示给子图。