我还是新的依赖注入,我尝试使用 MVP 设计模式实现我的应用程序。我为每个视图使用范围图。我决定在阅读this great article后,我的适配器应被视为View的一部分。
我的示例中的视图是片段。我创建了一个模块[称为 FragmentModule ],它提供了 Presenter 和 View 。
在我开始搞乱之前,模块只注入了 Fragment ,并通过调用带有所需参数的构造函数来提供 FragmentAdapter 。
模块:
@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;
// ... //
}
这可能仍然是#34;正确的做法"但我想讨论我目前的做法,所以继续阅读!
然后我再次重新编写它,以便 FragmentAdapter 引用 Fragment 实例。然后我在 FragmentAdapter 构造函数中指定了Context和Listener。
private MyFragment mFragment;
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment);
}
Adapter构造函数如下所示:
private Context mContext;
private CustomListener mListener;
public FragmentAdapter(MyFragment iFragment)
{
mContext = iFragment.getActivity();
mListener = iFragment;
// ... //
}
之后我决定出于某种原因我想将Context注入适配器。所以我继续说: 我也将 FragmentModule 注入了适配器,如下所示:
@Module(
overrides = true,
includes = BaseFragmentModule.class,
injects = {
FragmentAdapter.class,
MyFragment.class,
}
)
现在我必须学习如何以一种漂亮,干净的方式将 FragmentAdapter 注入到Fragment的作用域ObjectGraph中。首先,我从 FragmentAdapter 构造函数中调用 inject():
FragmentModule:
// ... //
private MyFragment mFragment;
// ... //
@Provides
@Singleton
public FragmentAdapter provideAdapter() {
return new FragmentAdapter(mFragment);
}
// ... //
FragmentAdapter :
@Inject Context mContext;
@Inject MyListener mListener;
public FragmentAdapter(MyFragment iFragment)
{
iFragment.getObjectGraph().inject(this);
// ... //
}
再次,出于某种原因(记得我正在学习..) - 我想让注入工作而不必将 Fragment 实例传递给 FragmentAdapter 构造函数,所以我最终在Module类中调用 inject():
@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注入实现Adapter和Fragment依赖?为什么?
非常感谢您的反馈!
答案 0 :(得分:1)
我看到它的方式,ObjectGraph.inject(...)
应该尽可能避免。相反,您希望执行构造函数注入:在构造函数中传递注入的依赖项。
您可以通过向构造函数添加@Inject
注释来执行此操作:
private final Context mContext;
private final MyListener mListener;
@Inject
public FragmentAdapter(Context context, MyListener listener)
{
mContext = context;
mListener = listener;
// ... //
}
现在,您不再需要provideAdapter()
,因为Dagger识别构造函数上的@Inject
注释。您需要提供我认为您已经在做的Context
和MyListener
个实例。
如果说过,我不相信MyListener
应该被注入。它不是您FragmentAdapter
的依赖项,而是一项功能。只需拨打setListener(MyListener)
课程中的Fragment
即可。
最后一句话,有时inject(...)
是无法避免的。特别是当您使用的是您没有管理的构造函数的类时(例如Activity
和Fragment
)。