Dagger - 快速依赖注入器(for android and java) (2)
单例(Singletons)给@Provides注释的函数或者可注入的类, 添加注释@Singlton, 构建的这个对象图表将使用唯一的对象实例。 @Provides @Singleton Heater provideHeater() { return new ElectricHeater(); } 可注入类的@Singleton注释也可以作为说明文档, 它提示那些潜在的维护者们:多个线程将共享唯一个对象实例。 @Singleton
class CoffeeMaker {
...
}
延迟注入某些情况下需要延迟初始化一个对象。对任意的对象T来说,你可以使用Lazy实现延迟初始化。Lazy只有当Lazy's get()函数调用时, 才会初始化T对象。如果T是个单例的对象, Lazy也将使用同一个对象进行注入操作。否则,每次注入都将生成自己的 Lazy对象。 当然, 任何随后调用Lazy.get()函数将返回之前构建好的T对象。 GridingCoffeeMaker {
@Inject Lazy<Grinder> lazyGrinder;
public void brew{
while (needsGrinding()) {
// Grinder created once on first call to .get() and cached.
.get().grind();
}
}
}
提供者注入(PROVIDER INJECTIONS)有些情况下, 你需要多个对象实例, 而不是仅仅注入一个对象实例。这时你可以利用Provider实现, 每次调用Provider的get()函数将返回新的T的对象实例。 BigCoffeeMaker ProviderFilterfilterProvider(int numberOfPots) {
...
for p = 0; < p++) {
makeraddFilter()); //new filter every time.
addCoffee(...);
percolate();
...
Dagger作者也提醒: 限定符(QUALIFIERS) 有些时候,单纯类型是不能够满足指定依赖的需求的。例如,一个复杂的Coffee maker程序可能需要不同的加热器。 @Qualifier
@Documented
@RetentionRUNTIME)
public @interface Named {
String value() default "";
你也可以创建自己的限定符注释, 也可以直接使用@Named, 给相应的成员变量添加限定符。这些限定符注释将与类型一起标记依赖关系。
ExpensiveCoffeeMaker @Inject @Named("water") waterHeater;
"hot plate"hotPlateHeater;
}
Supply qualified values by annotating the corresponding @Provides method.
provideHotPlateHeater(70);
}
provideWaterHeater93 依赖关系也可以同时有多重限定符注释。
静态注入(STATIC INJECTION)
Dagger可以注入静态变量。拥有@Inject静态变量的类必须在@Module的staticInjections中明确说明。 @Module(
staticInjections = LegacyCoffeeUtilsclass
LegacyModule {
可以使用ObjectGraph.injectStatics()注入静态变量:
ObjectGraph objectGraph ObjectGraphcreate(new LegacyModule());
objectGraphinjectStatics();
编译时有效性检查(COMPILE-TIME VALIDATION)Dagger包含一个annotation 处理器, 这个处理器检查module和注入的有效性。处理器非常严格, 若是有任何绑定是无效或者不完整的, 将引发编译错误。例如, 这个Module缺少Executor的对象绑定: @Module
DripCoffeeModule Executor executorCpuHeater);
编译时, javac将提示缺少对象绑定。
[ERROR] COMPILATION ERROR :
] error: No binding for javautilconcurrentExecutor
required by provideHeaterExecutor)
为了修正这个错误, 可以添加Executor的@Provides函数, 或者标记该Module为不完整的。不完整的Module允许缺少对象引用。 complete = false 在Module中若provide的类,没有在injects列表中使用, 将在编译时触发错误。
injects Exampleclass();
}
Chiller provideChillerElectricChiller 因为Eample.class的注入声明在Module中仅使用了Heater,而没有使用Chiller,因此将触发未使用绑定错误:
COMPILATION ERROR:
]: Graph validation failed: You have these unused @Provider methods:
1. coffeeDripCoffeeModuleprovideChiller()
Set library=true in your module to disable this check.
若是这个Module提供的对象绑定, 可能被injects列表中以外的类使用, 可以将改Module标记为library,以避免出错。 (
,
library true
为了在编译时检查所有的Module, 可以创建一个Module包含所有的程序Modules,annotation处理器将检测问题, 并报告。
includes = {
DripCoffeeModuleExecutorModuleclass
public CoffeeAppModule 当你将Dagger's jar文件包含到编译classpath中时, Annotation处理器自动运行。
编译时代码生成(COMPILE-TIME CODE GENERATION)Dagger的Annotation processor 可以生成源码文件, 例如CoffeeMaker$InjectAdapter.java o,DripCoffeeModule$ModuleAdapter. 这些文件是Dagger的实现细节。你没有必要直接使用这些类文件, 但可以通过这些进行调试。 Module重载(MODULE OVERRIDES) 若对同一个依赖关系有多个@Provides函数, Dagger 将会报错。但在有些情况下,是有必要替换production代码的, 比如测试和开发。 在@Module中可以使用overrides =true , 重载其绑定关系。 CoffeeMakerTest CoffeeMaker coffeeMakerheater;
@Before void setUp{
TestModule()).injectthis}
(
CoffeeMakerTestoverrides true
)
static TestModule {
{
return MockitomockHeater);
@Test testHeaterIsTurnedOnAndThenOffwhenisHotthenReturn(true);
brew();
verifytimes)).onoff 这种重载方式也很适合程序的小型变动, 例如付费版,免费版。
Replacing the real implementation with a mock for unit tests. Replacing LDAP authentication with fake authentication for development. For more substantial variations it's often simpler to use a different combination of modules. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |