Android 从Dagger模块方法调用inject()-错误的做法?
我还不熟悉依赖注入,我尝试使用MVP设计模式来实现我的应用程序。我为每个视图使用一个范围图。在通读之后,我决定将我的适配器视为视图的一部分 在我的示例中,视图是一个片段。我创建了一个模块[称为FragmentModule],它提供了演示者和视图 在我开始胡闹之前,模块只注入了片段,并通过调用其构造函数提供了片段适配器 模块:Android 从Dagger模块方法调用inject()-错误的做法?,android,mvp,dagger,Android,Mvp,Dagger,我还不熟悉依赖注入,我尝试使用MVP设计模式来实现我的应用程序。我为每个视图使用一个范围图。在通读之后,我决定将我的适配器视为视图的一部分 在我的示例中,视图是一个片段。我创建了一个模块[称为FragmentModule],它提供了演示者和视图 在我开始胡闹之前,模块只注入了片段,并通过调用其构造函数提供了片段适配器 模块: @Module( overrides = true, includes = BaseFragmentModule.class,
@Module(
overrides = true,
includes = BaseFragmentModule.class,
injects = {
MyFragment.class,
}
)
public class FragmentModule {
private MyFragment mFragment;
// ... // Other methods removed for clarity
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment.getActivity(), mFragment);
}
// ... //
}
FragmentAdapter构造函数看起来有点像这样:
private Context mContext;
private CustomListener mListener;
public FragmentAdapter(Context context, CustomListener listener)
{
mContext = context;
mListener = listener;
// ... //
}
private Context mContext;
private CustomListener mListener;
public FragmentAdapter(MyFragment iFragment)
{
mContext = iFragment.getActivity();
mListener = iFragment;
// ... //
}
这可能仍然是“正确的做法”,但我想讨论一下我目前的做法,所以请继续阅读
然后我再次重写它,以便FragmentAdapter引用Fragment实例。然后,我在碎片适配器构造函数中分配了上下文和侦听器
private MyFragment mFragment;
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment);
}
适配器构造函数如下所示:
private Context mContext;
private CustomListener mListener;
public FragmentAdapter(Context context, CustomListener listener)
{
mContext = context;
mListener = listener;
// ... //
}
private Context mContext;
private CustomListener mListener;
public FragmentAdapter(MyFragment iFragment)
{
mContext = iFragment.getActivity();
mListener = iFragment;
// ... //
}
之后,出于某种原因,我决定将上下文注入适配器。所以我继续说:
我让片段模块也注入适配器,如下所示:
@Module(
overrides = true,
includes = BaseFragmentModule.class,
injects = {
FragmentAdapter.class,
MyFragment.class,
}
)
现在我必须学习如何将FragmentAdapter以一种漂亮、干净的方式注入片段的作用域ObjectGraph。首先,我从FragmentAdapter构造函数调用了inject():
private final Context mContext;
private final MyListener mListener;
@Inject
public FragmentAdapter(Context context, MyListener listener)
{
mContext = context;
mListener = listener;
// ... //
}
碎片模块:
// ... //
private MyFragment mFragment;
// ... //
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment);
}
// ... //
碎片适配器:
@Inject Context mContext;
@Inject MyListener mListener;
public FragmentAdapter(MyFragment iFragment)
{
iFragment.getObjectGraph().inject(this);
// ... //
}
同样,出于某种原因(请记住我正在学习…)-我想让注入工作,而不必将片段实例传递给片段适配器构造函数,因此我最终从模块类中调用注入()
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
if (mAdapter == null) {
mAdapter = new FragmentAdapter();
mFragment.getObjectGraph().inject(mAdapter);
mAdapter.initialize(); // Code moved from constructor which depends on injected members
}
return mAdapter;
}
现在我很好奇,你认为这里最好的练习是什么?如何使用Dagger注入实现适配器和片段依赖关系?为什么
非常感谢您的反馈 在我看来,应该尽量避免使用
ObjectGraph.inject(…)
。相反,您希望进行构造函数注入:在构造函数中传递注入的依赖项
private MyFragment mFragment;
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment);
}
您可以通过向构造函数添加@Inject
注释来完成此操作:
private final Context mContext;
private final MyListener mListener;
@Inject
public FragmentAdapter(Context context, MyListener listener)
{
mContext = context;
mListener = listener;
// ... //
}
现在,您不再需要provideApter()
,因为Dagger可以识别构造函数上的@Inject
注释。您确实需要提供Context
和MyListener
实例,我相信您已经在这样做了
话虽如此,我认为不应该注入MyListener
。它不是您的片段适配器的依赖项,而是一项功能。只需从Fragment
类调用setListener(MyListener)
最后一句话,有时inject(…)
是不可避免的。特别是当您使用的类的构造函数不是您管理的(例如活动和片段)时。感谢您的输入Niek!我已经同意了。我同意你的话——事实上,我最终删除了以前使用的接口,我直接处理适配器中的事件——因为我认为这是视图的一部分。对还是错。。这是一个可扩展的列表视图。