只有一个方法可以创建给定的子组件,方法是使用plus()创建

Moh*_*ANE 1 java android dependency-injection dagger-2

我有一个Dagger子组件UserComponent,当用户登录应用程序时创建了一个Dagger子组件,下面有我的列表Subcomponents(例如:FriendsComponent,ProfileComponent,HomeComponent ...)。

我想要的是:创建一个名为ProfileComponent(在UserComponent下)的subComponent ,它具有两个Modules ProfileModulePostsModule

                         MainComponent
                             |
                =============|======================
               |                                   |
                |                                   |
          UserComponent                      WelcomeComponent
                |
       =========|============                  
       |                     |    
    ProfileComponent       HomeComponent
       |
       |
  =====================
  |                  |
 PostsModule        ProfileModule   
Run Code Online (Sandbox Code Playgroud)

(我希望这是可读的)

所以ProfileComponent应该包含以下内容:

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

   void inject(PostsFragment postsFragment);
   void inject(ProfileActivity profileActivity);
}
Run Code Online (Sandbox Code Playgroud)

这是用户子组件

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

           HomeComponent plus(HomeModule homeModule);

           ProfileComponent plus(PostsModule postsModule);

           ProfileComponent plus(ProfileModule profileModule);
        }
Run Code Online (Sandbox Code Playgroud)

此处在PostsFragment中完成了注入

protected void setUpComponent(DragonBloodComponent component) {
       mApp.getApp(getActivity()).getUserComponent()
               .plus(new PostsModule())
               .inject(this);
   }
Run Code Online (Sandbox Code Playgroud)

我得到这个错误

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

我这样做对吗?谢谢。

Jef*_*ica 5

ProfileComponent plus(PostsModule postsModule);
ProfileComponent plus(ProfileModule profileModule);
Run Code Online (Sandbox Code Playgroud)

这两个是不兼容的:看来您想要创建一个需要两个模块的ProfileComponent,但是您提供了两种不同的创建方法,而这两种方法都不需要。匕首恰巧警告您有关相互不兼容,然后警告您两者都不完整。

@Component docs的“子组件”部分所述,最简单的更改是将它们放在相同的方法声明中(强调我的意思):

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

看起来像这样:

ProfileComponent plus(PostsModule postsModule, ProfileModule profileModule);
Run Code Online (Sandbox Code Playgroud)

建筑商

或者,定义一个子组件构建器(请参见component builder),该子组件构建可以聚合所需的模块。然后,可以在需要的任何位置注入此子组件构建器,因此不需要注入Component即可调用该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();
   }
}
Run Code Online (Sandbox Code Playgroud)

并消耗:

@Inject ProfileComponent.Builder profileComponentBuilder;
ProfileComponent profileComponent = profileComponentBuilder
    .postsModule(yourPostsModule)
    .profileModule(yourProfileModule)
    .build();
Run Code Online (Sandbox Code Playgroud)