我正在使用具有简单MVP模式的Dagger 2。我有一个@PerApp
和@PerActivity
范围。我正在使用构造函数注入注入演示者依赖项,这使得这些演示者“可注入”(我不需要在活动模块中编写提供方法)。代码片段:
PerApp:
// AppComponent
@PerApp
@Component(modules = {AppModule.class, DataModule.class, NetworkModule.class})
public interface AppComponent {
LoginComponent plus(LoginModule loginModule);
MainComponent plus(MainModule mainModule);
}
// Example @PerApp module
@Module
public class NetworkModule {
@Provides
@PerApp
Retrofit providesRetrofit(){
...
}
}
PerActivity:
// LoginModule
@Module
public class LoginModule {
private final LoginActivity mLoginActivity;
public LoginModule(LoginActivity loginActivity) {
mLoginActivity = loginActivity;
}
@Provides
@PerActivity
Context providesContext() {
return mLoginActivity;
}
}
// LoginComponent
@PerActivity
@Subcomponent(
modules = LoginModule.class
)
public interface LoginComponent {
void inject(LoginActivity loginActivity);
}
的活动:
public class LoginActivity {
@Inject LoginPresenter mPresenter;
}
主讲人:
public class LoginPresenter {
@Inject
public LoginPresenter(Retrofit retrofit) {
...
}
}
它运作良好。我的问题是:提供LoginPresenter
的范围是什么?它会跟LoginActivity
一样吗?我应该用@PerActivity
或其他东西注释演示者的构造函数吗?
答案 0 :(得分:3)
这完全取决于您用于注射的组件。
让我们假设:
LoginActivity
的组件:
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = LoginActivityModule.class)
public interface LoginActivityComponent {
void inject(LoginActivity loginActivity);
}
ApplicationComponent
来提供@PerApp
范围内的对象如果您没有指定特定module
应该提供特定对象的方式(例如LoginPresenter
),那么您基本上是对component
说:
我需要一个
LoginPresenter
个实例。我不在乎谁创造了那个。只是弄清楚自己。
此组件检查是否有任何从属components
/ modules
知道如何创建它。如果没有,被询问的component
需要自己创建(在相关的匕首元素的帮助下)。
注入component
只能尝试引用来自同一范围的对象("创建")。因此,如果LoginActivityComponent
来自@PerActivity
,则它可以创建仅来自此范围的对象。
如果您未在LoginPresenter
中指定范围,则匕首将采用与注射组件相同的范围。如果明确指定@PerActivity
范围,它将匹配component
范围,一切都会正常。但是,如果您指定了不同的范围(例如@PerApp
),则您的应用无法正确构建,因为@PerApp
中没有任何类提供创建LoginPresenter
的方式。
Disclamer:我的解释可能很少有部分我已经简化了,所以它更容易理解(主要是关于谁做了什么)。我尽量不做任何与Dagger2本身的逻辑相矛盾的简化。
答案 1 :(得分:3)
我已经运行了一些测试来自行检查确定范围如何与构造函数注入一起工作,这是我的结果。
LoginPresenter
注入LoginActivity
: LoginComponent
- @PerActivity
范围(代码与我的第一篇文章完全相同)。
我试图将演示者注入2个变量:
public class LoginActivity {
@Inject LoginPresenter A;
@Inject LoginPresenter B;
}
LoginPresenter
注明:
A
和B
不同A
和B
相同A
和B
相同LoginPresenter
注入LoginActivity
和MainActivity
: LoginComponent
,MainComponent
- @PerActivity
范围(代码与我的第一篇文章完全相同)。
我试图将演示者注入两个不同的活动:
public class LoginActivity {
@Inject LoginPresenter A;
}
public class MainActivity {
@Inject LoginPresenter B;
}
LoginPresenter
注明:
A
和B
不同A
和B
不同A
和B
相同答案 2 :(得分:2)
在具有带有@Inject
批注的构造函数时,指定范围的方法似乎是使用范围来注释类:
@PerActivity
public class LoginPresenter {
@Inject
public LoginPresenter(Retrofit retrofit) {
...
}
}
我假设LoginPresenter
仅在LoginActivity
中注入,这意味着 Dagger 将仅提供一次并创建一个实例。如果您多次注入它,而没有范围注释,您将获得不同的实例。