[英]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
@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
更改(或可以更改)的程度,請繼續閱讀。
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
:
@Provides
方法中使用MembersInjector
。@Module
class BModule {
@Provides
static B provideB(MembersInjector<B> injector) {
B b = new B();
injector.injectMembers(b);
return b;
}
}
現在你可以在任何地方注入B
或Provider<B>
,根本不需要修改B
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.