[英]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.