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,以最少的代码为您提供生成器语法