Android 无效注入(活动活动)和SomeComponent getSomeComponent()之间的差异
通常在使用Dagger 2和android时,我有以下几点:Android 无效注入(活动活动)和SomeComponent getSomeComponent()之间的差异,android,dagger-2,Android,Dagger 2,通常在使用Dagger 2和android时,我有以下几点: @Singleton @Component(modules = {ApplicationModule.class}) public interface ApplicationComponent { void inject(MainActivity activity); } public class MainActivity extends Activity { @Inject SharedPreferen
@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类,它们是标准的
这两种方法的区别是什么?赞成和反对哪一个?可能是正确的还是错误的方法?如果查看
组件的生成代码,您会注意到它通过直接使用传递的活动引用设置注入字段来实现注入(MainActivity)
方法。
因此,这两种选择的作用是相同的
我更喜欢第一种方法有两个主要原因。首先,当字段被注释为这样时,字段被注入是非常清楚的,其次,它使代码更加干净。在您给出的示例中,您只注入了一个字段,很难看到它的好处,但我认为当您需要注入10个字段时,它会变得更加明显,您必须在onCreate()
中分配所有字段,并在组件中声明它们的getter。软件工程的建议是,我们应该尝试依赖抽象,而不是具体化
因此,您应该更喜欢在活动中使用@Inject
注释(摘要)进行字段注入,而不是从Dagger组件(具体)调用provision方法
为什么??您会注意到@Inject
注释是javax.Inject
包的一部分。这是一个将依赖注入API引入Java的标准,它是Java的一部分。还有其他DI框架,如Guice和Toothick,可以使用这些注释。如果将来必须切换DI框架,那么使用@Inject
注释会更容易。是的,您确实需要更改DI框架。是最近已退役的流行DI框架的一个示例
为了举例说明,让我们以您的活动为例,添加一些依赖项,并提取一个方法进行注入,如下所示:
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框架支持它们)。如果您已更改为一个新的类似GUI的框架,则只需重写您的方法:
@VisibleForTesting
protected void injectMembers() {
GuiceLikeInjector.getInjector(this).injectMembers();
}
相反,如果您使用.getSharedReferences()
,getFoo()
手动注入这些字段,效果不是很好-您必须更改许多代码行。相关:谢谢,我做了搜索,但没有找到。谢谢。我最初问的原因是因为一位新同事想用第二种方式进行重构。我很难说服他们选择一种更好/更正常的方式,谢谢你帮助我建立了一个更好的方式argument@i我不是乔希,我很高兴这有帮助。尽管语法看起来有点不寻常,JSR330还是很棒!