我正在尝试通过实现虚拟Java控制台应用程序来学习Dagger 2,我有这个类。
public class Lemonader {
private Water water;
private Lemon lemon;
private Sugar sugar;
private WaterCooler waterCooler;
public Lemonader(Water water, Lemon lemon, Sugar sugar) {
this.water = water;
this.lemon = lemon;
this.sugar = sugar;
this.waterCooler = new WaterCooler(water); // TODO remove hard dependency via Dagger 2
}
public void makeLemonade() {
System.out.println("Making lemonade..");
waterCooler.coolItUpTheWater();
System.out.println("Lemonade has been made with " + water.getAmount() + " liters of water, " + sugar.getAmount() + " kilograms of sugar and " + lemon.getQuantity() + " lemons.");
}
这就是我创建Lemonader
对象
public class LemonaderHelper {
public Lemonader getLemonader(int waterAmount, boolean isWaterHot, int lemonQuantity, int sugarAmount) {
Water w = new Water();
w.setAmount(waterAmount);
w.setCold(isWaterHot);
Lemon l = new Lemon();
l.setQuantity(lemonQuantity);
Sugar s = new Sugar();
s.setAmount(sugarAmount);
Lemonader lemonader = new Lemonader(w, l, s);
return lemonader;
}
}
我想通过Dagger 2注入Lemonader的WaterCooler
成员但我找不到通过water
构造函数的Lemonader
实例的方法(我尝试创建提供的模块) Water
和WaterCooler
。它有效,但它创建了一个新的water
实例,而不是传递来自Lemonader
构造函数的实例。我怎么能通过Dagger 2做到这一点?任何帮助将不胜感激。
答案 0 :(得分:2)
Dagger 2用于在图中自动提供依赖关系。因为WaterCooler只接受一个依赖关系并且它不在图中,因此使用WaterCooler作为实现细节,我完全按照你的方式使用它:
this.waterCooler = new WaterCooler(water);
但是,如果您希望能够替换实现,您可能会考虑注入相关对象,其中有一个方法需要一个参数(水)并返回冷水源。您可能会认为这只是一个构造函数包装器,但实际上它遵循factory method pattern。
interface SourceOfCoolWaterFactory {
/** Probably returns a water cooler. Might return a refrigerator. */
SourceOfCoolWater createCoolWaterSource(Water water);
}
啊哈哈!现在您可以注入SourceOfCoolWaterFactory
,并创建一个只调用new WaterCooler(water)
的实现。这将删除您在代码注释中标识的硬依赖关系,允许您替换所需的任何实现 - 包括测试的模拟。重要的是,这也允许您混合图表中的依赖项,例如当您的WaterCooler耗尽电池时:
public class WaterCoolerFactory implements {
private final Provider<Electricity> electricityProvider;
@Inject public WaterCoolerFactory(Provider<Electricity> electricityProvider) {
this.electricityProvider = electricityProvider;
}
@Override
public SourceOfCoolWater createCoolWaterSource(Water water) {
return new WaterCooler(water, electricityProvider.get());
}
}
你现在有一个可以在Dagger中绑定的实现,允许你的Lemonader注入SourceOfCoolWaterFactory而不是直接调用WaterCooler构造函数,并正确地将图形生成的依赖项如Electricity
添加到构造函数依赖项中,如{{ 1}}。
尽管Dagger实际上没有提供任何自动化工厂的方法,但谷歌有一个名为AutoFactory的姐妹项目,它可以为任何JSR-330依赖注入框架生成注入工厂(例如Dagger,Guice) ,和Spring),它位于名为Google Auto的包中,用于值对象和Java服务的代码生成器。使用AutoFactory,您可以使用一些注释来注释WaterCooler,AutoFactory将创建一个可以在Dagger中绑定的实现:
Water