【问题标题】:Dagger 2 issue with sub-component and a component with a dependency component子组件和具有依赖组件的组件的 Dagger 2 问题
【发布时间】:2016-05-04 14:22:05
【问题描述】:

我正在开发 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.

我阅读了很多关于 dagger 2 子组件的帖子。但是,它们并没有按预期工作。我有什么遗漏吗?

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:

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

    您的LoginComponent 取决于 ApplicationComponent 声明如下:

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

    这意味着使用您的LoginComponent,您可以注入LoginComponent 知道的所有内容。这就是LoginModule 提供的所有内容,可以通过构造函数注入创建的可能对象*和来自ApplicationComponent暴露 对象。

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

    这就是说,对于INeedThis,这些都不是真的。

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

    我不知道您如何/为什么将 component 添加为 module。如果这是一个错字,并且您将 MySubModule 添加到您的组件中,您只需将以下内容添加到 expose 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 接口以对象暴露到子图。

    【讨论】:

    • 设置子组件的想法很难理解。您能告诉我如何设置子组件吗?基本上,我需要一个带有子组件的 ApplicationComponent。以 ApplicationComponent 作为依赖项的所有其他组件都应该可以访问子组件。如果这不是常态,请纠正我!
    • @Renjith 请记住,此站点是针对特定编程问题而非一般编码信息的。您需要如何或为什么需要使用子组件取决于您要完成的任务,我无法为您回答这个问题。我已经更新了答案,如果您仍然需要更多信息,您应该寻找一些实际的教程并自己尝试一下
    • 感谢您编辑的答案!我确实尝试将其合并到我的应用程序中,但没有成功。也许,我的目标可能会略有不同。但是,我深入挖掘了一些 github 示例并使其工作。
    猜你喜欢
    • 2015-06-17
    • 2015-08-07
    • 2017-02-26
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多