簡體   English   中英

Dagger2:如何在不注入其合成器類的情況下注入字段?

[英]Dagger2: How to inject field without injection of it's compositor class?

我的 A 類需要 C 類的依賴注入。 C 類是 B 類的組件(B 有 C 作為字段)。 A類可以不注入B而注入C嗎?

[A 注入]->(B 未注入 A)->[C 注入 B]

我是我的真實項目,我需要將字段注入一個類,但不需要向包含(直接或間接)該字段的所有類添加注入隊列。

目前我在 B 類中有異常:

Exception in thread "main" java.lang.NullPointerException
        at B.log(B.java:28)
        at A.b_foo(A.java:28)
        at App.main(App.java:36)

請指教。 代碼:

應用程序.java

import dagger.Component;
import javax.inject.Singleton;
 
public class App {
  @Singleton
  @Component(
      modules = {
              CModule.class
             }
  )
  public interface AppRunner {
    A instance();
  }

  public static void main(String[] args) {
    AppRunner appRunner = DaggerApp_AppRunner.builder().build();
    appRunner.instance().foo();
  }
}

一個.java

import javax.inject.Inject;

public class A {
    private final B b;

    @Inject
    A() {
        this.b = new B();
    }

    public void foo() {
        b.log();
    }
}

B.java

import javax.inject.Inject;

public class B {

  @Inject
  C c;

  B() { }

  public void log() {
      c.log("in C log"); //java.lang.NullPointerException here because B was not injected before C
  }
}

C.java

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;

@Singleton
public final class C {
  private final List<String> logs = new ArrayList<>();

  @Inject
  C() {}

  public void log(String msg) {
    logs.add(msg);
  }
}

模塊

import dagger.Module;
import dagger.Provides;

@Module
public abstract class CModule {
    @Provides
  static C provideC() {
        return new C();
    }
}

更新:我可以在沒有 B 注入的情況下擁有完全工作的代碼嗎? 我的 A 班知道 Dagger。 但是A一定不能有B注入。

您在B類中有一個@Inject字段,並且您希望能夠在A獲得一個完全初始化的B

選項 1:只需將@Inject添加到構造函數

就是這樣。 您不需要將依賴項移動到構造函數中。

public class B {

  @Inject
  C c;

  @Inject // This annotation is the only thing added.
  B() { }

  public void log() {
      c.log("in C log");
  }
}

如果這甚至超出了您想在B更改(或可以更改)的程度,請繼續閱讀。

選項 2:注入MembersInjector<B>

Dagger 包含接口MembersInjector ,它的功能與聽起來完全一樣。 您可以將MembersInjector<B>注入A ,並使用它分兩步構造B

@Inject
A(MembersInjector<B> injector) {
    this.b = new B();
    injector.injectMembers(b);
}

由於MembersInjector是Dagger 的一部分而不是JSR-330,這意味着A類必須了解Dagger。 這可能是一個問題,但您可以輕松地將此邏輯移出A

選項 3:在@Provides方法中使用MembersInjector

@Module
class BModule {
    @Provides
    static B provideB(MembersInjector<B> injector) {
        B b = new B();
        injector.injectMembers(b);
        return b;
    }
}

現在你可以在任何地方注入BProvider<B> ,根本不需要修改B

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM