【问题标题】:Dagger2 Basics - Field Injection - Not workingDagger2 基础 - 场注入 - 不工作
【发布时间】:2017-06-24 15:25:46
【问题描述】:

我正在尝试使用 Dagger2 进行字段注入。我意识到在方法注入的情况下我需要手动调用注入。我主要是尝试为汽车注入引擎。引擎在运行时决定并注入。

数据是这样的

汽车接口

import dagger.Binds;

public interface Car {  

    public void run();
}

汽车实施

public class Volkswagen implements Car {

@Inject
public Engine engine;

    public void run() {
        System.out.println("About to Run");
        engine.start();
    }
}

引擎接口

public interface Engine {
    public String start();
}

引擎实现

public class Ferrari4Cylinder implements Engine {

    @Override
    public String start() {
        return "Ignition----Vroom-- Vroom-- Sweet Purring Sound";
    }
}

汽车模块

public  class CarModule{
    @Provides @Singleton
    Car provideCar(){
        return new Volkswagen();
    }   
}

引擎模块

@Module
public class EngineModule {
    @Provides @Singleton
    public Engine provideEngine(){
        return new Ferrari4Cylinder();
    }
}

组件类

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {
    public Car provideCar();
    void inject(Car car);
}

主要方法

public class Main {

    public static void main(String[] args) {
        MyCarComponent carComponent= DaggerMyCarComponent.builder().build();
        Car car = carComponent.provideCar();    
        carComponent.inject(car);
        car.run();
    }
}

出于某种原因: Car.run() 方法总是返回 null,因为引擎永远不会被注入。 线程“主”java.lang.NullPointerException 中的异常

有人可以帮忙看看这里发生了什么吗?

2016 年 9 月 2 日更新: 我发现以下将组件更改为指向实际实现的工作如下所示。不知道为什么另一个没有,但它帮助我在这个问题上取得了进展。

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {
    public Volkswagen provideCar();
    void inject(Volkswagen car);
}

希望这对尝试解决 Dagger 中的字段注入问题的人们有所帮助。

【问题讨论】:

  • 如果 CAR 接口不存在,此代码可以正常工作。我遇到了错误还是缺少符号?
  • 我仍然无法理解为什么它不起作用。我像您一样制作了虚拟项目,并且现场注入在该项目中不起作用。我进行了您在上次 cmets 中建议的更改,将其更改为大众汽车,但我仍然无法成功运行该项目。它仍然给出空指针异常。
  • 你能解决这个问题吗?如果你能把代码发给我,我可以看看?

标签: java dagger-2 dagger


【解决方案1】:

您需要使用@Inject 注释您的引擎字段。我也相信你会 需要为您的注入方法提供实现的类(大众汽车,而不仅仅是 Car)。

public class Volkswagen implements Car {

  @Inject public Engine engine;

  public void run() {
    System.out.println("About to Run");

    engine.start();
  }
}

--

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {

  public Car provideCar();
  void inject(Volkswagen car);

}

【讨论】:

  • 谢谢,我想我有 EngineModule 但在问题中错过了它。在组件中添加大众汽车,实际上使它工作。但这迫使我更改 provideCar 方法以返回大众汽车而不是汽车。这很奇怪,因为我认为整个想法是导航对象图,并找出依赖关系。
【解决方案2】:

您似乎忘记将EngineModule 添加到MyCarComponent

为了进行字段注入,您应该在 Car 类的 Engine 上添加 @Inject 注释。但鼓励尽可能避免现场注入。而是考虑这样做:

public class Volkswagen implements Car {

  private final Engine engine;

  public Volkswagen(Engine engine) {
    this.engine = engine;
  }

}

然后在CarModule

@Provides
@Singleton
static Car provideCar(Engine engine) {
  return new Volkswagen(engine);
}

另外,这样你就不需要组件接口上的inject方法了。

记得给组件加上EngineModule,这样dagger就可以提供Engine了。

【讨论】:

  • 谢谢,这是一个错字。我还发现如果 Car Interface 不存在。它工作得很好。将更新我的问题。我遇到错误了吗?
  • 我不确定您的意思是“汽车界面不存在”。你能解释一下吗?
  • 如果我将代码更改为如下所示,它可以工作 public class Volkswagen { @Inject public Engine engine; public void run() { // TODO 自动生成的方法存根 System.out.println("About to Run");启动引擎();然后把组件类改成这样 public Volkwagen provideCar();无效注入(大众汽车);
  • 这是因为组件不知道如何提供 Volkswagen 对象(在其任何模块中都没有 @Provides 注释方法返回 Volkswagen),它知道如何提供 Car。跨度>
  • @benji,为什么“鼓励避免现场注入”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
  • 2014-07-08
  • 1970-01-01
相关资源
最近更新 更多