Dagger 和 mvp - 演示者应该使用 dagger 进行注射
Dagger and mvp - should presenter use dagger for injection
我开始觉得在mvp里,dagger不应该用在presenter里。构造匕首的常用方法是使用全局组件并使用子组件来确定图形的范围。这个全局组件通常会在创建 appmodule.java class 时将 applicationContext 作为参数。给定应用程序上下文使生活更轻松。
没关系,但如果我使用全局组件甚至子组件中的模块,则应传入上下文。这意味着如果我用匕首注入演示器,它将绑定到 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" 并从组件中注入?所以我在想为什么这种匕首模式让我强迫演示者有一个上下文?
即使我们使用子组件,它仍然依赖于 AppComponent,然后在我们的测试用例中,我们必须处理正在创建的应用程序上下文,以便让匕首注入。
所以我认为应该有一个规则——在 MVP 中更喜欢手动构造函数注入而不是匕首注入
因为 class 不应该知道它是如何注入的。被注入的东西不应该关心它是如何被注入的。
dagger.android 根据已接受的答案概述了我正在谈论的问题。
依赖注入对 Android 组件(活动等)很有用,主要是因为这些 classes 必须具有无参数构造函数,以便框架可以构造它们的实例。任何不需要无参数构造函数的 class 都应该在其构造函数中简单地接收所有依赖项。
编辑: 关于如何获取对 AppComponent
.
的引用的旁注
Application
是-一个Context
,而Context#getApplicationContext()
返回的Context
通常是Application
实例。但这并不一定如此。我知道 可能 不是这种情况的一个地方是在模拟器中。所以这个转换可能会失败:
presenterComponent = ((MyApplication) context).getAppComponent();
可变静态字段通常是邪恶的,在 Android 上更是如此。但是 IMO,你可以逃脱它的一个地方是你的 Application
class。只有一个 Application
实例,并且在调用 Application#onCreate()
之前不会存在任何其他组件。所以让你的 AppComponent
成为 MyApplication
的静态字段是可以接受的,在 onCreate()
中初始化它,并提供一个静态 getter,只要你只调用 [=39] =] 来自其他组件的生命周期方法。
我也同意"Not having android related code in your presenter is always a good idea, and dagger does not interfere with that."
的说法
首先,我想提请注意的是,从 dagger 2.10 版本开始,您可以使用 dagger.android
包来简化活动和片段中的注入,因此您不需要使用 MyApplication
跨应用投射。
其次,为什么不将 WelcomePresenter
注入 activity 或片段,反之亦然?
我开始觉得在mvp里,dagger不应该用在presenter里。构造匕首的常用方法是使用全局组件并使用子组件来确定图形的范围。这个全局组件通常会在创建 appmodule.java class 时将 applicationContext 作为参数。给定应用程序上下文使生活更轻松。
没关系,但如果我使用全局组件甚至子组件中的模块,则应传入上下文。这意味着如果我用匕首注入演示器,它将绑定到 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" 并从组件中注入?所以我在想为什么这种匕首模式让我强迫演示者有一个上下文?
即使我们使用子组件,它仍然依赖于 AppComponent,然后在我们的测试用例中,我们必须处理正在创建的应用程序上下文,以便让匕首注入。
所以我认为应该有一个规则——在 MVP 中更喜欢手动构造函数注入而不是匕首注入 因为 class 不应该知道它是如何注入的。被注入的东西不应该关心它是如何被注入的。
dagger.android 根据已接受的答案概述了我正在谈论的问题。
依赖注入对 Android 组件(活动等)很有用,主要是因为这些 classes 必须具有无参数构造函数,以便框架可以构造它们的实例。任何不需要无参数构造函数的 class 都应该在其构造函数中简单地接收所有依赖项。
编辑: 关于如何获取对 AppComponent
.
Application
是-一个Context
,而Context#getApplicationContext()
返回的Context
通常是Application
实例。但这并不一定如此。我知道 可能 不是这种情况的一个地方是在模拟器中。所以这个转换可能会失败:
presenterComponent = ((MyApplication) context).getAppComponent();
可变静态字段通常是邪恶的,在 Android 上更是如此。但是 IMO,你可以逃脱它的一个地方是你的 Application
class。只有一个 Application
实例,并且在调用 Application#onCreate()
之前不会存在任何其他组件。所以让你的 AppComponent
成为 MyApplication
的静态字段是可以接受的,在 onCreate()
中初始化它,并提供一个静态 getter,只要你只调用 [=39] =] 来自其他组件的生命周期方法。
我也同意"Not having android related code in your presenter is always a good idea, and dagger does not interfere with that."
的说法首先,我想提请注意的是,从 dagger 2.10 版本开始,您可以使用 dagger.android
包来简化活动和片段中的注入,因此您不需要使用 MyApplication
跨应用投射。
其次,为什么不将 WelcomePresenter
注入 activity 或片段,反之亦然?