为什么我得到null而不是@Inject-ed字段?

时间:2016-05-10 18:41:20

标签: java dagger-2

在下面的代码中,我希望得到一个新的Soap对象(行#07),但我得到null。我在这里缺少什么?

01| public class ExampleUnitTest {
02|     @Test
03|     public void DaggerTest() throws Exception {
04|         MyComponent myComponent = DaggerMyComponent.create();
05|         IThing thing = myComponent.getThing();
06|         Impl impl = thing.getImpl();
07|         ISoap soap = impl.soap;
08|         Assert.assertNotNull(soap); // fails here: soap is null!
09|     }
10| }
11|
12| interface ISoap{}
13| class Soap implements ISoap{}
14|
15| class Impl{
16|     @Inject public ISoap soap;
17| }
18|
19| @Module
20| class MyModule {
21|     @Provides IThing getThing(){ return new Thing(); }
22|     @Provides ISoap getSoap() { return new Soap(); }
23| }
24|
25| @Component(modules = MyModule.class)
26| interface MyComponent {
27|     IThing getThing();
28|     ISoap getSoap();
29| }
30|
31| interface IThing{
32|     Impl getImpl();
33| }
34|
35| class Thing implements IThing{
36|     @Override public Impl getImpl() { return new Impl(); }
37| }

1 个答案:

答案 0 :(得分:2)

要使用匕首场注入(使用@Inject注释字段),您需要在创建之后手动注入对象

class Impl {
     @Inject public ISoap soap; // requires field injection
}

// will only work with something like this
Impl myImpl new Impl();
component.inject(myImpl); // inject fields

这不是你在做什么。您自己在模块创建对象并期望它被初始化。 创建了该对象,没有初始化它。

如果您使用模块,则需要返回初始化的对象。

// to create your thing, you need a soap. REQUIRE it in your parameters,
// then create your _initialized_ object (you could also use a setter)
@Provides IThing getThing(ISoap soap) { return new Thing(soap); }

然后你可以使用

IThing thing = myComponent.getThing();

它会有肥皂。

此外,我不知道你是通过从getter返回一个新对象来做什么的。

class Thing implements IThing{
    @Override public Impl getImpl() { return new Impl(); }
}

如果你自己再次致电new,那你就是在尝试做匕首工作。

你应该好好看看构造函数注入。然后,您可以将模块作为一个整体删除,它不会为您的示例添加任何功能。

有很多优秀而详细的教程,例如:我关于dagger basics的博文,应该对匕首有一个很好的介绍。