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

Why am I getting null instead of the @Inject-ed field?

在下面的代码中,我希望得到一个新的 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| }

要使用匕首字段注入(用 @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

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

如果你使用模块,你需要return你的初始化对象。

// 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();

它会有肥皂。


此外,我不知道您要通过 return 从 getter 中创建一个新对象来做什么。

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

如果您自己给 new 打电话,您又在尝试做匕首工作。


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

有很多很好很详细的教程,例如我的博客 post 关于 dagger basics 应该很好地介绍了匕首。