通常在使用Dagger 2和android时我有以下内容:
@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();
}
}
但最近我看到了这个:
/Folder B
file.docx
fileB.docx
fileC.docx
pythonDeleteScript.py
folderA/
folderB/
folderC/
folderD/
我省略了DemoApplication类和Module类,它们是标准的。
这两种方法有什么区别?亲们的亲和?也许是对还是错?
答案 0 :(得分:2)
软件工程的dependency inversion principle表明我们应该尝试依赖于抽象而不是结核。
出于这个原因,您应该更喜欢在Activity中进行字段注入的@Inject
注释(摘要),而不是从Dagger组件(具体)调用提供方法。
为什么呢?您会注意到@Inject
注释是javax.inject
包的一部分。这是作为JSR330的一部分引入Java的依赖注入API的标准。还有其他DI框架,例如Guice和Toothpick,可以使用这些注释。如果您将来必须切换DI框架,那么使用@Inject
注释会更容易。是的,确实需要更改DI框架。 Roboguice是最近退休的流行DI框架的示例。
为了说明这一点,让我们进行您的Activity,添加一些依赖项,并提取一个注入方法,如下所示:
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。它非常有效! (翻译:您可以重复使用JSR330 @Inject
注释,因为新的DI框架支持它们)。如果您已经更改为类似Guice的新框架,那么您需要做的就是重写您的方法:
@VisibleForTesting
protected void injectMembers() {
GuiceLikeInjector.getInjector(this).injectMembers();
}
相反,如果您使用.getSharedPreferences()
,getFoo()
手动注入了这些字段,那么它不是很有效 - 您必须更改许多代码行。
答案 1 :(得分:1)
如果您查看Component
生成的代码,您会注意到它通过使用您传递的活动参考直接设置注入字段来实现inject(MainActivity)
方法。
所以两个选项都做同样的事情。
我更喜欢第一种方法有两个主要原因。首先,当它们被注释时,注入字段会更加清晰,其次,它使代码更加清晰。在这个示例中,您给了注入一个字段并且更难以看到好处,但是我认为当您需要注入10个字段时,它们将变得更加明显,您必须在{}中分配所有字段{1}},并在组件中为它们声明getter。