假设我正在制造一辆汽车,我有几个不同实施的刹车豆
class Car {
@Inject
Car(@BrakeType(value="abs")Brake frontBrake, @BrakeType(value="nonabs")Brake rearBrake) { }
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface BrakeType {
String value();
}
interface Brake {}
@BrakeType(value="abs")
class AbsBrakeImpl implements Brake {
@Inject AbsBrakeImpl() {}
}
@BrakeType(value="nonabs")
class BrakeImpl implements Brake {
@Inject BrakeImpl() {}
}
Run Code Online (Sandbox Code Playgroud)
为什么我的CarModule必须为特定的制动类型定义@Provides?自定义注释类型@BrakeType不应该足以确定要注入哪个impl?或者这需要使用反射,dagger2不使用?
@Module
public class CarModule {
@Provides @BrakeType("abs")
public Brake absBrake() {
return new AbsBrakeImpl();
}
@Provides @BrakeType("nonabs")
public Brake nonabsBrake() {
return new BrakeImpl();
}
}
Run Code Online (Sandbox Code Playgroud)
Dagger不查看类上的限定符注释,仅查看@Provides或@Binds方法.因此,@BrakeType(value="abs")对您的类的注释没有任何影响.
编写代码的更规范的方法是:
class AbsBrakeImpl implements Brake {
@Inject AbsBrakeImpl() {}
}
class BrakeImpl implements Brake {
@Inject BrakeImpl() {}
}
@Module
abstract class CarModule {
@Binds @BrakeType("abs")
abstract Brake absBrake(AbsBrakeImpl impl);
@Binds @BrakeType("nonabs")
abstract Brake nonabsBrake(BrakeImpl impl);
}
Run Code Online (Sandbox Code Playgroud)
请注意,由于您拥有@Inject实现的构造函数,因此您可以简单地使用Dagger @Bind将实现直接绑定到适当的限定接口.
反射在这里可能不是一个大问题,因为它会在编译时发生。
我没有查看源代码,但 dagger 只是一个注释处理器——它注册为在使用一组给定注释时被调用。虽然仅限定符可能足以找出您的意图,但我可以想到以下原因为什么这不是最佳解决方案。
javax.inject.Qualifier是更大 API 的一部分,也可能被其他库在不同的上下文中使用。因此,您可能不希望 dagger 为方法生成代码,只是因为它用限定符注释。
另一个原因可能是,由于可以创建自定义限定符,因此 dagger 必须检查每个模块中每个方法的每个注释,然后依次确定该注释本身是否被注释,以查看@Qualifier该方法是否对该方法感兴趣。它。这是不必要的开销。
可能还有更多原因,但这里列出的这两个似乎足以让 dagger 用户使用某种合同:@Provides。
注释不会影响代码的性能,并且附加注释不会造成任何损害,因此按照它们的方式处理它利大于弊。
| 归档时间: |
|
| 查看次数: |
5506 次 |
| 最近记录: |