我正在使用Dagger将依赖项注入到 Android应用程序,我偶然发现了一个我不完全确定的问题 如何以干净的方式解决。
我想要实现的目标是实现帮助并将其注入我的内部 活动,并让这些助手也包含注入成员。
什么有用
我的助手注入的活动:
public class MyActivity extends Activity {
@Inject SampleHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyApplication) getApplication()).inject(this);
Log.i("debug", "helper = " + helper);
Log.i("debug", "helper context = " + helper.context);
}
}
创建对象图的应用程序:
public class MyApplication extends Application {
private ObjectGraph graph;
@Override
public void onCreate() {
super.onCreate();
graph = ObjectGraph.create(getModules());
}
private Object[] getModules() {
return new Object[] { new MyModule(this) };
}
public void inject(Object target) {
graph.inject(target);
}
}
当我直接实例化SampleHelper类时,注入效果非常好, 它反过来接收注入的应用程序上下文:
@Singleton
public class SampleHelper {
@Inject public Context context;
@Inject
public SampleHelper() {}
}
使用以下模块:
@Module(
injects = { MyActivity.class },
complete = false,
library = true
)
public class MyModule {
private final MyApplication application;
public MyModule(MyApplication application) {
this.application = application;
}
@Provides @Singleton Context provideApplicationContext() {
return application;
}
}
什么行不通
但是,当我将辅助接口与其实现分离时:
public interface SampleHelper {
}
@Singleton
public class SampleHelperImpl implements SampleHelper {
@Inject public Context context;
@Inject
public SampleHelperImpl() {}
}
并将其添加到匕首模块中:
public class MyModule {
...
// added this method
@Provides @Singleton public SampleHelper provideSampleHelper() {
return new SampleHelperImpl();
}
...
}
我的SampleHelperImpl中没有注入上下文,正如我所期望的那样。现在,我想这是因为SampleHelperImpl是通过直接构造函数调用而实现的 那个注入启动的构造函数调用,因为MyModule#provideApplicationContext()甚至没有被调用,所以我的猜测是我错过了一些关于Dagger的东西(很可能,因为我以前的DI体验只包含了Spring)。
关于如何在我的注入帮助器实现中以“干净的Dagger”方式注入我的上下文的任何想法?
非常感谢!
答案 0 :(得分:18)
这是一个相当古老的问题,但我认为你想要的是:
@Provides @Singleton public SampleHelper provideSampleHelper(SampleHelperImpl impl) {
return impl;
}
这样Dagger会创建你的SampleHelperImpl
并因此注入它。
答案 1 :(得分:1)
如果有人感兴趣,在dagger模块中实现@Provides方法时,你可以获得这样的匕首处理对象实例:
@Provides @Singleton public SampleHelper provideSampleHelper(Context context) {
SampleHelper helper = new SampleHelperImpl();
helper.setContext(context);
return helper;
}
这样可行,但我仍然觉得它有点笨拙,因为我必须明确地调用我的助手设置器(通常是你想用注射去掉的)。
(如果有人找到更好的解决方案,我会稍等一下)
答案 2 :(得分:1)
(适用于Dagger v1.0.1)
确保使用适配器注入。通过反射注射,匕首显然不会对@Provides
物体进行传递注射。我认为这是一个错误。
答案 3 :(得分:0)
在注入正确的上下文方面,您可能需要查看此示例https://github.com/square/dagger/tree/master/examples/android-activity-graphs。