Dagger 2将子组件添加到父组件

时间:2018-06-29 11:20:26

标签: android dagger-2 subcomponent

您好,我在理解dagger 2以新方式添加子组件(在dagger 2.7中添加)时遇到了问题。请参见下面的示例:

@Component(modules = {AppModule.class, MainActivityBinder.class})
@Singleton
interface AppComponent
{
   inject(MyApplication _)
}

@Subcomponent(modules = ActivityModule.class)
interface ActivitySubcomponent
{
   inject(MainActivity _)

   @Subcomponent.Builder
   interface Builder
   {
      @BindInstance
      Builder activity(Activity activity)

      ActivitySubcomponent build();
   }
}

初始步骤:我有AppComponent是我的根组件,为AppModule提供了单例(改造,okhttp等)。在ActivitySubcomponent中,我为ActivityModule提供了为该活动指定的依赖项。现在必须将子组件添加到AppComponent中,因此,我以新的方式创建了名为MainActivityBinder的指定模块,该模块具有@ Module.subcomponents批注,指向该子组件的绑定,但是我有第一个问题,应该怎么做在绑定模块的主体中​​?

@Module(subcomponents = ActivitySubcomponent.class)
public class MainActivityBinder
{
  //what body of this class should be ??
}

我知道,这个想法是我可以绑定子组件或其构建器。第二个问题是何时绑定构建器,以及何时绑定子组件?例如,我的ActivitySubcomponent必需的活动上下文,因此我创建了在ActivityModule中提供上下文给MainActivityBinder的构建器?第三个问题是如何调用组件构建器以及如何为应用程序组件获取子组件?在标准子组件工厂中,我添加了AppComponent方法来返回子组件,并且我可以定义参数(例如,给活动上下文,如下所示)

@Component(modules = {AppModule.class})
@Singleton
interface AppComponent
{
   ActivitySubcomponents newActivitySubcomponents(Activity activity);

   inject(MyApplication _);
}

// in MainActivity
appComponent.newActivitySubcomponents(this).build().inject(this);

是否已在新的子组件添加方法中实现了此行为?

1 个答案:

答案 0 :(得分:0)

  1. 您的模块MainActivityBinder允许为空,如果没有其他可绑定的东西,则应为空。当您仅使用Module.includes时(例如,要将模块列表保留在一个位置而不是在多个组件之间进行复制),空模块(仅用于注释)也很有用。注释上的subcomponents属性足以使Dagger理解您要执行的操作。

  2. 当且仅当它没有@BindsInstance方法或可实例化模块(Dagger无法实例化)时,才可以注入FooSubcomponent或Provider。如果所有模块都是接口,抽象类或具有公共零参数构造函数的模块,则可以直接注入子组件。否则,您应该注入子组件构建器。

  3. 您可以通过创建一个在AppComponent上返回它的方法来访问子组件构建器,就像对图形中存在的任何绑定一样:

    @Component(modules = {AppModule.class, MainActivityBinder.class})
    @Singleton
    interface AppComponent {
      ActivitySubcomponent.Builder activitySubcomponentBuilder();
    
      inject(MyApplication _)
    }
    

    您也可以将其注入您选择的对象中。

    @Inject ActivitySubcomponent.Builder activitySubComponentBuilder;
    activitySubComponentBuilder.activity(this).build().inject(this);
    
    // You can also inject a Provider<ActivitySubcomponent.Builder> if you want,
    // which is a good idea if you are injecting this directly into your Application.
    // Your Application will outlive your Activity, and may need to inject several
    // instances of the Activity across application lifetime.
    @Inject Provider<ActivitySubcomponent.Builder> activitySubComponentBuilderProvider;
    activitySubComponentBuilderProvider.get().activity(this).build().inject(this);
    

尽管您可以轻松地在组件上调用方法(返回Builder或返回子组件),但注入子组件构建器似乎没有太多优势,但是注入有很多优点建造者:

  • Dagger不能告诉您是否在组件上调用方法,因此即使未使用子组件,Dagger也会生成并编译代码。 Dagger 可以告诉您是否曾经尝试注入构建器,因此,如果没有子组件/构建器注入并且没有方法,Dagger将跳过为子组件生成代码。
  • 如果您的代码库足够大,您必须将其拆分为不同的目标进行编译,则工厂方法技术可能会陷入某些依赖周期,其中应用程序的组件和模块依赖于所有内容,您只能进入组件本身的子组件。使用可注射子组件构建器,您可以选择更多有关如何进入子组件或构建器的选项。