J'ai vu l'exemple suivant sur le site Web Dagger 2 :
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
et la documentation:
Lorsqu'une nouvelle instance est demandée, Dagger obtiendra les valeurs de paramètres requises et invoquera ce constructeur.
Quand j'écris un module pour fournir un Thermosiphon
comme
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon() {
return new Thermosiphon(???);
}
}
le constructeur Thermosiphon
nécessite toujours un Heater
comme argument, rendant inutile toute "l'injection automatique des dépendances du constructeur".
J'ai essayé
return new Thermosiphon(null);
et
return new Thermosiphon();
(constructeur vide) et espérait que Dagger2 capterait que je voulais que le Heater
manquant soit injecté, mais le chauffage du Thermosiphon
fourni est toujours nul;
J'ai vérifié que mes HeaterComponent
/HeaterModule
fonctionnent bien et sont capables de fournir un Heater
.
Est-ce que je comprends mal toute la fonctionnalité de "Dagger satisfait les dépendances des constructeurs pour vous" ou est-ce que je manque quelque chose?
Si vous utilisez des modules, alors si vous avez deux modules fournisseur liés au même composant, vous pourrez leur permettre de voir le réchauffeur comme un paramètre constructeur.
@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;
}
}
Mais avec l'injection de constructeur, vous serez également en mesure de fournir des objets de cette portée donnée, ou des objets non étendus, tant qu'ils ont un @Inject
constructeur.
Par exemple,
@Singleton
@Component // no modules
public interface SingletonComponent {
Thermosiphon thermosiphon();
Heater heater();
void inject(Something something);
}
Et
@Singleton
public class Heater {
@Inject
public Heater() {
}
}
Et
@Singleton
public class Thermosiphon {
private Heater heater;
@Inject
public Thermosiphon(Heater heater) {
this.heater = heater;
}
}
Ou
@Singleton
public class Thermosiphon {
@Inject
Heater heater;
@Inject
public Thermosiphon() {
}
}
D'une part, puisque vous avez annoté le constructeur de Thermosiphon
avec @Inject
, vous n'avez pas besoin d'un @Provides
méthode. Dagger utilise ce constructeur pour créer une instance en cas de besoin. Annotez simplement la classe Thermosiphon
avec @Singleton
pour conserver le comportement singleton.
Si vous souhaitez utiliser un @Provides
, et pour répondre pleinement à votre question, vous pouvez spécifier Heater
comme paramètre de la méthode:
@Module
public class ThermosiphonModule {
@Provides
@Singleton
Thermosiphon provideThermosiphon(Heater heater) {
return new Thermosiphon(heater);
}
}