通常在使用 Dagger 2 和 android 时,我有以下内容:
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
void inject(MainActivity activity);
}
public class MainActivity extends Activity {
@Inject SharedPreferences mSharedPrefs;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((DemoApplication) getApplication())
.getComponent()
.inject(this);
}
}
但最近我看到了这个:
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
SharedPreferences getSharedPreferences();
}
public class MainActivity extends Activity {
SharedPreferences mSharedPrefs;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSharedPrefs = ((DemoApplication) getApplication())
.getComponent().getSharedPreferences();
}
}
我省略了 DemoApplication 类和 Module 类,它们是标准的。
这两种方法有什么区别?两者的优缺点?也许是正确或错误的方式?
最佳答案
软件工程的 dependency inversion principle 建议我们应该尝试并依赖抽象而不是具体。
出于这个原因,您应该更喜欢 @Inject
注释(抽象)用于您的 Activity 中的字段注入(inject),而不是从 Dagger 组件(具体)调用配置方法。
为什么?您会注意到 @Inject
注释是 javax.inject
包的一部分。这是作为 JSR330 的一部分引入 Java 的依赖注入(inject) API 的标准。还有其他 DI 框架,例如 Guice 和 Toothpick,可以使用这些注释。如果以后必须切换 DI 框架,使用 @Inject
注释会更容易。是的,确实需要更改 DI 框架。 Roboguice 是一个最近被淘汰的流行 DI 框架的例子。
为了说明这一点,让我们以您的 Activity,添加一些依赖项,并提取这样的注入(inject)方法:
public class MainActivity extends Activity {
@Inject SharedPreferences mSharedPrefs;
@Inject Foo foo;
@Inject Bar bar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@VisibleForTesting
protected void injectMembers() {
((DemoApplication) getApplication())
.getComponent()
.inject(this);
}
}
一个狂野的(新的)DI 框架出现了!您现在必须更改您的应用程序才能快速使用它!您使用 JSR330。它 super 有效! (翻译:您可以重复使用您的 JSR330
@Inject
注释,因为新的 DI 框架支持它们)。如果您已更改为新的类似 Guice 的框架,您需要做的就是重写您的方法: @VisibleForTesting
protected void injectMembers() {
GuiceLikeInjector.getInjector(this).injectMembers();
}
相比之下,如果您使用
.getSharedPreferences()
手动注入(inject)这些字段, getFoo()
就不是很有效 - 您必须更改很多代码行。关于android - void injection(Activity activity) 和 SomeComponent getSomeComponent() 的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41843947/