Dagger 2注入构造函数的参数
Dagger 2 injecting parameters of constructor
我在 Dagger 2 website 上看到了下面的例子:
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
和文档:
When a new instance is requested, Dagger will obtain the required
parameters values and invoke this constructor.
当我写一个模块来提供一个Thermosiphon
like
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon() {
return new Thermosiphon(???);
}
}
Thermosiphon
构造函数仍然需要一个 Heater
作为参数,导致整个 'automatic injection of constructor dependencies' 无用。
我试过了
return new Thermosiphon(null);
和
return new Thermosiphon();
(空构造函数)并希望 Dagger2 能够接收到我希望注入缺失的 Heater
,但所提供的 Thermosiphon
的加热器始终为空;
我已验证我的 HeaterComponent
/ HeaterModule
工作正常并且能够提供 Heater
。
我是否完全误解了 'Dagger satisfies constructor dependencies for you' 的全部功能,还是我遗漏了什么?
首先,由于您已经使用 @Inject
注释了 Thermosiphon
的构造函数,因此您不需要 @Provides
方法。 Dagger 在需要时使用此构造函数创建实例。只需用 @Singleton
注释 Thermosiphon
class 本身以保留单例行为。
如果您确实想使用 @Provides
方法并完整回答您的问题,您可以将 Heater
指定为该方法的参数:
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon(Heater heater) {
return new Thermosiphon(heater);
}
}
如果您正在使用模块,那么如果您有两个提供程序模块绑定到同一个组件,那么您将能够允许它们将加热器视为构造函数参数。
@Module
public class HeaterModule {
@Provides
@Singleton
Heater heater() {
return new Heater(); // if not using @Inject constructor
}
}
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon thermosiphon(Heater heater) {
return new Thermosiphon(heater); // if not using @Inject constructor
}
}
@Singleton
@Component(modules={ThermosiphonModule.class, HeaterModule.class})
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
public class CustomApplication extends Application {
private SingletonComponent singletonComponent;
@Override
public void onCreate() {
super.onCreate();
this.singletonComponent = DaggerSingletonComponent.builder().build(); //.create();
}
public SingletonComponent getSingletonComponent() {
return singletonComponent;
}
}
但是通过构造函数注入,您还可以提供给定范围内的对象,或无范围的对象,只要它们具有 @Inject
构造函数即可。
例如,
@Singleton
@Component // no modules
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
和
@Singleton
public class Heater {
@Inject
public Heater() {
}
}
和
@Singleton
public class Thermosiphon {
private Heater heater;
@Inject
public Thermosiphon(Heater heater) {
this.heater = heater;
}
}
或
@Singleton
public class Thermosiphon {
@Inject
Heater heater;
@Inject
public Thermosiphon() {
}
}
我在 Dagger 2 website 上看到了下面的例子:
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
和文档:
When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.
当我写一个模块来提供一个Thermosiphon
like
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon() {
return new Thermosiphon(???);
}
}
Thermosiphon
构造函数仍然需要一个 Heater
作为参数,导致整个 'automatic injection of constructor dependencies' 无用。
我试过了
return new Thermosiphon(null);
和
return new Thermosiphon();
(空构造函数)并希望 Dagger2 能够接收到我希望注入缺失的 Heater
,但所提供的 Thermosiphon
的加热器始终为空;
我已验证我的 HeaterComponent
/ HeaterModule
工作正常并且能够提供 Heater
。
我是否完全误解了 'Dagger satisfies constructor dependencies for you' 的全部功能,还是我遗漏了什么?
首先,由于您已经使用 @Inject
注释了 Thermosiphon
的构造函数,因此您不需要 @Provides
方法。 Dagger 在需要时使用此构造函数创建实例。只需用 @Singleton
注释 Thermosiphon
class 本身以保留单例行为。
如果您确实想使用 @Provides
方法并完整回答您的问题,您可以将 Heater
指定为该方法的参数:
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon(Heater heater) {
return new Thermosiphon(heater);
}
}
如果您正在使用模块,那么如果您有两个提供程序模块绑定到同一个组件,那么您将能够允许它们将加热器视为构造函数参数。
@Module
public class HeaterModule {
@Provides
@Singleton
Heater heater() {
return new Heater(); // if not using @Inject constructor
}
}
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon thermosiphon(Heater heater) {
return new Thermosiphon(heater); // if not using @Inject constructor
}
}
@Singleton
@Component(modules={ThermosiphonModule.class, HeaterModule.class})
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
public class CustomApplication extends Application {
private SingletonComponent singletonComponent;
@Override
public void onCreate() {
super.onCreate();
this.singletonComponent = DaggerSingletonComponent.builder().build(); //.create();
}
public SingletonComponent getSingletonComponent() {
return singletonComponent;
}
}
但是通过构造函数注入,您还可以提供给定范围内的对象,或无范围的对象,只要它们具有 @Inject
构造函数即可。
例如,
@Singleton
@Component // no modules
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
和
@Singleton
public class Heater {
@Inject
public Heater() {
}
}
和
@Singleton
public class Thermosiphon {
private Heater heater;
@Inject
public Thermosiphon(Heater heater) {
this.heater = heater;
}
}
或
@Singleton
public class Thermosiphon {
@Inject
Heater heater;
@Inject
public Thermosiphon() {
}
}