Android 匕首及;嵌套注射

Android 匕首及;嵌套注射,android,dependency-injection,dagger,Android,Dependency Injection,Dagger,我正在使用将依赖项注入到 Android应用程序,我偶然发现了一个我不完全确定的问题 如何以干净的方式解决问题 我试图实现的是实例化助手并将它们注入到我的系统中 活动,并让这些助手也包含注入成员 什么有效 正在注射我的助手的活动: 公共类MyActivity扩展活动{ @注射样本辅助物; @凌驾 创建时受保护的void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); ((MyApplication)getApplic

我正在使用将依赖项注入到 Android应用程序,我偶然发现了一个我不完全确定的问题 如何以干净的方式解决问题

我试图实现的是实例化助手并将它们注入到我的系统中 活动,并让这些助手也包含注入成员

什么有效

正在注射我的助手的活动:

公共类MyActivity扩展活动{
@注射样本辅助物;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
((MyApplication)getApplication()).inject(this);
Log.i(“调试”、“帮助程序=“+helper”);
Log.i(“调试”、“助手上下文=“+helper.context”);
}
}
创建对象图的应用程序:

公共类MyApplication扩展应用程序{
私有对象图;
@凌驾
public void onCreate(){
super.onCreate();
graph=ObjectGraph.create(getModules());
}
私有对象[]getModules(){
返回新对象[]{newmymodule(this)};
}
公共无效注入(对象目标){
图.注入(目标);
}
}
当我直接实例化一个SampleHelper类时,注入非常有效, 依次接收注入的应用程序上下文:

@Singleton
公共类SampleHelper{
@注入公共语境;
@注入
公共SampleHelper(){}
}
使用以下模块:

@模块(
injects={MyActivity.class},
完成=错误,
库=真
)
公共类MyModule{
私人最终申请;
公共MyModule(MyApplication应用程序){
这个应用程序=应用程序;
}
@提供@Singleton上下文ProviderApplicationContext(){
退货申请;
}
}
什么不起作用

但是,当我将助手接口与其实现分离时:

公共接口SampleHelper{
}
@独生子女
公共类SampleHelperImpl实现SampleHelper{
@注入公共语境;
@注入
公共SampleHelperImpl(){}
}
并将其添加到匕首模块:

公共类MyModule{
...
//增加了这个方法
@提供@Singleton public SampleHelper provideSampleHelper(){
返回新的SampleHelperImpl();
}
...
}
上下文并没有像我预期的那样注入到我的SampleHelperImpl中。现在,我想这是因为SampleHelperImpl是通过直接构造函数调用实例化的,而不是 该注入启动了构造函数调用,因为MyModule#provideApplicationContext()甚至没有被调用,所以我猜我缺少了Dagger的一些东西(这很可能是因为我以前的DI体验只包括Spring)

关于如何以“干净的匕首”的方式将我的上下文注入我的注入助手实现中,有什么想法吗


非常感谢

如果有人感兴趣,在dagger模块中实现@Provides方法时,您可以获得dagger处理的对象实例,如下所示:

@提供@Singleton public SampleHelper provideSampleHelper(上下文){
SampleHelper=新的SampleHelperImpl();
setContext(context);
返回助手;
}
这是可行的,但我仍然觉得有点笨拙,因为我必须显式地调用我的helpers setters(通常是您希望通过注入消除的)


(我将稍等片刻,以防有人提出更好的解决方案)

在注入正确的上下文方面,您可能希望查看此示例。

(适用于Dagger v1.0.1)


确保您正在使用适配器注入。使用反射注入,dagger显然不会对
@提供的
对象进行传递注入。我认为这是一个bug。

这是一个相当老的问题,但我认为您想要的是:

@Provides @Singleton public SampleHelper provideSampleHelper(SampleHelperImpl impl) {
    return impl;
}

通过这种方式,Dagger将创建您的
SampleHelperImpl
,并将其注入。

感谢您的回复:我已经遇到了这个示例(没有太多;)。事实上,在现实生活中的应用程序中,您需要注入正确的上下文。但我最初的问题有点笼统:将Helper接口与实现分离会阻止@Inject在实现中工作,因为Helper实例化不再由Dagger直接处理。我现在也在努力使用Dagger,并且具有与您类似的配置。我需要将活动的实例注入helpers,而不是应用程序本身,但在其他方面非常类似。这就是为什么我要问你一个问题:为什么要将上下文作为成员注入
SampleHelper
,而不是作为构造函数参数?在我的例子中,通过构造函数参数注入失败,因此我想知道它是否有什么特别之处,应该避免。我理解这是离题的,但如果您能提供帮助,我将不胜感激。事实上,我现在将上下文作为构造函数参数传递(如下面的回答中所述),尽管它不是直接注入构造函数本身,而是作为dagger模块中@Provides方法的一部分传递(它可以工作)。我最初的想法是删除所有与分配成员有关的代码,这要感谢dagger,但我无法让它像spring injection那样易于使用。尽管如此,我知道它们的工作方式和约束条件并不相同,dagger仍然带来了很多。嗨,谢谢你的回复。也许你可以看看我的问题?这听起来很像我的问题。但你能澄清两件事吗:1/我认为它没有使用反射来进行注射?(我想你所说的“反射注入”是指什么,还是指基于注释的注入?)2/适配器注入是指什么:在dagger模块中使用@Provides进行注入?dagger提供了两种设置
@Inject
a的方法