Java 只有一个方法可以创建由plus()创建的给定子组件

Java 只有一个方法可以创建由plus()创建的给定子组件,java,android,dependency-injection,dagger-2,Java,Android,Dependency Injection,Dagger 2,我有一个名为UserComponent的Dagger子组件,是在用户登录应用程序时创建的,下面是子组件的列表(例如:FriendsComponent、ProfileComponent、HomeComponent…) 我想要的是:创建一个名为ProfileComponent(在UserComponent下)的子组件,该组件包含两个模块ProfileModule和PostsModule: MainComponent

我有一个名为
UserComponent
的Dagger子组件,是在用户登录应用程序时创建的,下面是
子组件的列表(例如:FriendsComponent、ProfileComponent、HomeComponent…)

我想要的是:创建一个名为
ProfileComponent
(在UserComponent下)的子组件,该组件包含两个模块
ProfileModule
PostsModule

                         MainComponent
                             |
                =============|======================
               |                                   |
                |                                   |
          UserComponent                      WelcomeComponent
                |
       =========|============                  
       |                     |    
    ProfileComponent       HomeComponent
       |
       |
  =====================
  |                  |
 PostsModule        ProfileModule   
(我希望这是可读的)

因此,组件应包含以下内容:

@UserScope
@Subcomponent(
       modules = {PostsModule.class, ProfileModule.class}
)
public interface ProfileComponent {

   void inject(PostsFragment postsFragment);
   void inject(ProfileActivity profileActivity);
}
这是用户子组件

@UserScope
@Subcomponent(
       modules = UserModule.class
)
public interface UserComponent {

           HomeComponent plus(HomeModule homeModule);

           ProfileComponent plus(PostsModule postsModule);

           ProfileComponent plus(ProfileModule profileModule);
        }
在这里注射,在断片后

protected void setUpComponent(DragonBloodComponent component) {
       mApp.getApp(getActivity()).getUserComponent()
               .plus(new PostsModule())
               .inject(this);
   }
我得到这个错误

error: Only one method can create a given subcomponent..profile.ProfileComponent is created by: [plus(PostsModule), plus(ProfileModule)]

我这样做对吗?谢谢。

我对子组件不是最熟悉的,但我认为您得到它的原因是因为您的概要文件组件包含PostModules.class作为子组件,然后您试图将其再次注入到PostsFragment类中。

我对子组件不是最熟悉的,但我认为您之所以会这样做,是因为您的概要文件组件包含PostModules.class作为子组件,然后您试图将其再次注入到PostsFragment类中

ProfileComponent plus(PostsModule postsModule);
ProfileComponent plus(ProfileModule profileModule);
这两个是不兼容的:看起来您想要创建一个需要两个模块的ProfileComponent,但是您提供了两种不同的方法来创建一个,并且两个模块都不需要。Dagger在警告你两者都不完整之前,会提醒你彼此之间的不相容性

最简单的更改,如的“子组件”部分所述,是将它们放在相同的方法声明中(重点是):

子组件也可以通过父组件或子组件上的工厂方法声明。该方法可以有任何名称,但必须返回子组件。工厂方法的参数可以是子组件的任意数量的模块,但必须至少包括那些没有可见的无参数构造函数的模块

看起来是这样的:

ProfileComponent plus(PostsModule postsModule, ProfileModule profileModule);
建设者 另一种方法是,定义一个(cf.)来聚合所需的模块。然后,可以将此子组件生成器注入到您需要的任何位置,因此无需注入组件即可调用
plus
方法。如果您的子组件中需要更多的模块,这也可能使代码更具可读性

@UserScope
@Subcomponent(
       modules = {PostsModule.class, ProfileModule.class}
)
public interface ProfileComponent {

   void inject(PostsFragment postsFragment);
   void inject(ProfileActivity profileActivity);

   /**
    * With this you can inject a ProfileComponent.Builder from within
    * the classes that UserComponent provides, or expose it on your enclosing 
    * (sub)component if you'd like. Dagger writes the implementation.
    *
    * Of course, you can skip Modules with zero-arg constructors, because Dagger
    * doesn't need to be provided an instance of those.
    */
   @Subcomponent.Builder interface Builder {
       Builder postsModule(PostsModule postsModule);
       Builder profileModule(ProfileModule profileModule);
       ProfileComponent build();
   }
}
和消费:

@Inject ProfileComponent.Builder profileComponentBuilder;
ProfileComponent profileComponent = profileComponentBuilder
    .postsModule(yourPostsModule)
    .profileModule(yourProfileModule)
    .build();
这两个是不兼容的:看起来您想要创建一个需要两个模块的ProfileComponent,但是您提供了两种不同的方法来创建一个,并且两个模块都不需要。Dagger在警告你两者都不完整之前,会提醒你彼此之间的不相容性

最简单的更改,如的“子组件”部分所述,是将它们放在相同的方法声明中(重点是):

子组件也可以通过父组件或子组件上的工厂方法声明。该方法可以有任何名称,但必须返回子组件。工厂方法的参数可以是子组件的任意数量的模块,但必须至少包括那些没有可见的无参数构造函数的模块

看起来是这样的:

ProfileComponent plus(PostsModule postsModule, ProfileModule profileModule);
建设者 另一种方法是,定义一个(cf.)来聚合所需的模块。然后,可以将此子组件生成器注入到您需要的任何位置,因此无需注入组件即可调用
plus
方法。如果您的子组件中需要更多的模块,这也可能使代码更具可读性

@UserScope
@Subcomponent(
       modules = {PostsModule.class, ProfileModule.class}
)
public interface ProfileComponent {

   void inject(PostsFragment postsFragment);
   void inject(ProfileActivity profileActivity);

   /**
    * With this you can inject a ProfileComponent.Builder from within
    * the classes that UserComponent provides, or expose it on your enclosing 
    * (sub)component if you'd like. Dagger writes the implementation.
    *
    * Of course, you can skip Modules with zero-arg constructors, because Dagger
    * doesn't need to be provided an instance of those.
    */
   @Subcomponent.Builder interface Builder {
       Builder postsModule(PostsModule postsModule);
       Builder profileModule(ProfileModule profileModule);
       ProfileComponent build();
   }
}
和消费:

@Inject ProfileComponent.Builder profileComponentBuilder;
ProfileComponent profileComponent = profileComponentBuilder
    .postsModule(yourPostsModule)
    .profileModule(yourProfileModule)
    .build();

嘿,Jeff,谢谢你提供了令人惊讶的、有详细文档记录的答案。我喜欢Builder方法并希望实现它,那么我是否必须为所有组件添加Builder,并从UserComponent中删除“plus”方法?谢谢。@Mohamed您可以一次为一个子组件选择一个生成器而不是
plus
,它们不必都是相同的。我还没有尝试使用同一组件的生成器和“plus方法”,但是如果您喜欢该生成器并喜欢从该组件进行访问,那么也可以在UserComponent上使用一个方法返回ProfileComponent.Builder,从而使您的生成器语法只需最少的代码更改。当然,如果您只是在需要的地方插入一个构建器,那么从组件中删除它可能是最好的选择。好的,那么UserComponent呢?现在看起来有很多问题让我感到抱歉,我只是有点困惑在删除了不完整的返回ProfileComponent的单参数
加上
方法之后,您的UserComponent有三种可能的结果:(1)一个双参数
加上
方法,返回一个
ProfileComponent
,如上所述;(2) 一个零参数方法,返回
ProfileComponent.Builder
,如果您已经定义了一个;或者(3)既不是1也不是2,因为只要
@Inject
你的
ProfileComponent.Builder
你就可以在任何需要它的地方使用它,而不必检索或保存
UserComponent
。嘿,Jeff,我一直在测试你的响应,我在这一点上卡住了:我创建了UserComponent Builder,但是,我为每个子组件提供的所有这些附加方法呢?我的意思是dagger怎么知道InboxComponent在UserComponent下,而没有像我使用“plus”方法那样提到它嘿Jeff,谢谢你提供了一个令人惊讶的有文档记录的答案。我喜欢构建器方法并想要实现它,所以我必须为我的所有组件添加构建器并删除“plus”吗我的UserComponent中的方法?谢谢。@Mohamed您可以一次为一个子组件选择一个生成器而不是
plus
,它们不必都是相同的。我还没有尝试使用同一组件的生成器和“plus方法”,但是如果您喜欢该生成器并喜欢从该组件进行访问,您还可以在UserComponent上使用一个方法返回ProfileComponent.Builder,以最少的代码为您提供生成器语法