我开始在mvp中思考,不应该在演示者中使用匕首。构造匕首的常用方法是使用全局组件并使用子组件来确定图形的范围。这个全局组件通常将applicationContext作为创建appmodule.java类的参数。给出应用程序上下文可以使生活更轻松。
这一切都很好,但是如果我使用全局组件或甚至子组件中的模块,则应该传入上下文。这意味着如果我向presenter注入dagger,它将绑定到applicationContext。这使得测试成为junit非常困难。 Android代码不应该在演示者中。
所以我问的是,只在活动片段广播接收器和服务中使用匕首是最好的做法吗?就mvp架构而言。另一种解决方案可能是设计另一个匕首组件,但不是与appcomponent或applicationContext无关的子组件。常见的做法是什么?
更新 让我们看一个真实的例子:
通常我们会在应用程序覆盖中创建一个像这样的appComponent:
public class MyApplication extends Application {
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = initDagger(this);
}
public AppComponent getAppComponent() {
return appComponent;
}
protected AppComponent initDagger(PomeloApplication application) {
return DaggerAppComponent.builder()
.appModule(new AppModule(application))
.build();
}}
然后例如在演示者中我们将在构造函数中执行此操作:
public WelcomePresenter(Context context) {
super(context);
presenterComponent = ((MyApplication) context).getAppComponent();
presenterComponent.inject(this);
}
因为我想要匕首提供者的应用程序上下文,我最终强迫调用者依赖于上下文对象。基本上,在获得上下文之前,您无法获取AppComponent模块,因此您可以将其转换为“MyApplication”并从组件中注入?所以我在想为什么这个匕首模式让我强迫主持人有一个背景?
即使我们使用了一个subComponent,它仍然依赖于AppComponent,然后在我们的测试用例中,我们必须处理正在创建的应用程序上下文以获得注入的匕首。
所以我认为应该有一个规则 - 在MVP中更喜欢手动构造器注入而不是匕首注入 因为班级不应该知道它是如何注入的。注射的东西不应该关心它是如何注射的。
dagger.android按照接受的答案概述了我所说的问题。
答案 0 :(得分:1)
依赖注入对Android组件(活动等)很有用,主要是因为这些类必须具有无参数构造函数,因此框架可以构造它们的实例。任何不需要具有no-arg构造函数的类都应该只在其构造函数中接收所有依赖项。
修改:关于如何获得对AppComponent
的引用的附注。
Application
是Context
,Context
返回的Context#getApplicationContext()
通常是Application
个实例。但事实并非如此。我所知道的一个地方可能不是这种情况是在模拟器中。所以这个演员会失败:
presenterComponent = ((MyApplication) context).getAppComponent();
可变静态字段通常是邪恶的,在Android上更是如此。但IMO,你可以逃脱的地方就在你的Application
课程中。只有Application
的一个实例,在调用Application#onCreate()
之前不会存在任何其他组件。因此,只要您只从其他生命周期方法中调用getter,就可以使AppComponent
成为MyApplication
的静态字段,在onCreate()
初始化它,并提供静态getter。组件。
答案 1 :(得分:1)
我也同意声明"在演示者中没有与Android相关的代码总是一个好主意,并且匕首不会干扰它。"
首先,我想引起注意的是,从匕首版本2.10开始,您可以使用dagger.android
包,这简化了活动和片段中的注入,因此您不需要使用MyApplication
在应用程序中投射。
其次,为什么不将WelcomePresenter
注入活动或片段,反之亦然?