java - Dagger2:如何在不注入合成器类的情况下注入字段?
问题描述
我的 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();
}
}
爪哇
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);
}
}
CModule.java
import dagger.Module;
import dagger.Provides;
@Module
public abstract class CModule {
@Provides
static C provideC() {
return new C();
}
}
更新:我可以在没有 B 注入的情况下拥有完全工作的代码吗?我的A班知道Dagger。但是A必须没有B注入。
解决方案
您在 class 中有一个@Inject
字段B
,并且您希望能够在其中完全B
初始化A
选项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 包含 interface 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:MembersInjector
在@Provides
方法中使用。
@Module
class BModule {
@Provides
static B provideB(MembersInjector<B> injector) {
B b = new B();
injector.injectMembers(b);
return b;
}
}
B
现在您可以在任何地方注入Provider<B>
,而无需进行任何修改B
。
推荐阅读
- c - 需要了解 pthread_mutex_lock() 和 pthread_cond_wait() 和 pthread_cond_signal() 的一种用法
- ios - IOS 10+ Persistence Store Container 将父上下文设置为主上下文
- android - How can I display two or multiple errors in same showError field
- react-native - React Native 搜索下拉菜单
- vb.net - VB.NET 日期/时间格式
- r - R:如何从坐标的tibble创建多线串sf
- fiware - “fiware-servicepath”标头值与通知的上下文响应的数量不匹配
- django-forms - 关于 Django 管理面板中行程部分的自定义 HTML 表单
- html - Bootstrap - 获取特定网格(列下的列)
- javascript - 取决于弹出窗口的表格数据,父级的表格数据显示项目不同