I saw the following example on the Dagger 2 website:
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
and the documentation:
When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.
When I write a Module to provide a Thermosiphon
like
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon() {
return new Thermosiphon(???);
}
}
the Thermosiphon
constructor still requires a Heater
as an argument, rendering the whole 'automatic injection of constructor dependencies' useless.
I tried
return new Thermosiphon(null);
and
return new Thermosiphon();
(empty constructor) and hoped for Dagger2 to pick up that I wanted the missing Heater
to be injected, yet the Heater of the provided Thermosiphon
is always null;
I verified though my HeaterComponent
/ HeaterModule
are working fine and are able to provide a Heater
.
Do I completey misunderstand the whole feature of 'Dagger satisfies constructor dependencies for you' or am I missing something?
Use @Inject to annotate the constructor that Dagger should use to create instances of a class. When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor. class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon(Heater heater) { this.
Inject values at runtime with UI in Dagger2:pureMathModule("Book Name") . build() . inject(this); The difference between DaggerComponent create() and in build() is - create() works when no runtime argument is passed into the constructor, else we use build() method.
@Inject is a Java annotation for describing the dependencies of a class that is part of Java EE (now called Jakarta EE). It is part of CDI (Contexts and Dependency Injection) which is a standard dependency injection framework included in Java EE 6 and higher.
Constructor Injection is the act of statically defining the list of required dependencies by specifying them as parameters to the class's constructor.
If you're using modules, then if you have two provider modules bound to the same component, then you'll be able to allow them to see the heater as a constructor parameter.
@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;
}
}
But with constructor injection, you will also be able to provide objects of that given scope, or unscoped objects, as long as they have a @Inject
constructor.
For example,
@Singleton
@Component // no modules
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
And
@Singleton
public class Heater {
@Inject
public Heater() {
}
}
And
@Singleton
public class Thermosiphon {
private Heater heater;
@Inject
public Thermosiphon(Heater heater) {
this.heater = heater;
}
}
Or
@Singleton
public class Thermosiphon {
@Inject
Heater heater;
@Inject
public Thermosiphon() {
}
}
For one, since you've annotated the constructor of Thermosiphon
with @Inject
, you don't need an @Provides
method. Dagger uses this constructor to create an instance when needed. Just annotate the Thermosiphon
class itself with @Singleton
to preserve the singleton behavior.
If you do want to use an @Provides
method, and to answer your question fully, you can specify the Heater
as a parameter to the method:
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon(Heater heater) {
return new Thermosiphon(heater);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With