假设我正在建造一辆汽车并且我有几个具有不同实施的制动豆
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() {}
}
为什么我的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();
}
}
答案 0 :(得分:6)
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);
}
请注意,由于您在实现的构造函数上有@Inject
,因此您只需使用Dagger的@Bind
将实现直接绑定到适当的合格接口。
答案 1 :(得分:1)
对于记录,您可以使用自己的限定符注释(如BrakeType),或者只使用Dagger中的@Named。 使用最后一个,您的代码将类似于:
@Inject @Named("abs") Brake frontBrake;
@Inject @Named("nonabs") Brake rearBrake;
在你的模块上:
@Provides @Named("abs") static Brake provideAbsBrake() {
return new AbsBrakeImpl();
}
@Provides @Named("nonabs") static Brake provideNonAbsBrake() {
return new BrakeImpl();
}
请记住使用Dagger名称约定(例如提供前缀)来获取大部分内容。在你的模块上尝试使用所有@Provides方法静态,这样做结果实现不需要实例化它。
简而言之,提供和限定符协同工作,因此您需要两者。
答案 2 :(得分:1)
@Inject constructor
表示在您的情况下提供类本身的类型,这意味着您提供AbsBrakeImpl
类型和BrakeImpl
类型,因此当您尝试注入{{1}时},dagger无法找到提供者。
Brake
中的限定符不起作用,因为类类型是唯一的,我们不需要添加限定符。
因此,在您的情况下,或者您必须使用@Inject constructor
明确告诉Dagger,或者使用
CarModule
答案 3 :(得分:0)
这里的反思可能不是一个大问题,因为它会在编译时发生。
我没有查看source code,但是dagger只是一个注释处理器 - 只要使用一组给定的注释,它就会被注册。虽然单凭限定符可能足以找出你的意图,但我可以想到以下原因,为什么这不是最佳解决方案。
total = 12
print ("I will play a game, you will choose 1, 2, or 3, and I will do the same, and I should always win, do you want to play?")
yesnoA = input("Yes or No?")
if yesnoA == yes:
print ("Yay, your turn!")
turnAA = input('Your First Move')
if turnAA == 1:
print ("I choose 3")
total = total - 4
print ("Total = ",total)
else:
if turnAA == 2:
print ("I choose 2")
total = total - 4
print ("Total = ",total)
else:
if turnAA == 3:
print ("I choose 1")
total = total - 4
print ("Total = ",total)
else:
print ("Cheater, try again")
else:
yesnoB = input("Ok, you sure?")
if yesnoB == yes:
print ("Yay, your turn")
turnAA = input('Your First Move')
if turnAA == 1:
print ("I choose 3")
total = total - 4
print ("Total = ",total)
else:
if turnAA == 2:
print ("I choose 2")
total = total - 4
print ("Total = ",total)
else:
if turnAA == 3:
print ("I choose 1")
total = total - 4
print ("Total = ",total)
else:
print ("Cheater, try again")
else:
print ("Well, goodbye")
是更大的API的一部分,也可能在不同的上下文中被其他库使用。所以你可能不希望匕首为方法生成代码,只是因为它是用限定符注释的。
另一个原因可能是因为有可能创建自定义限定符,dagger必须检查每个模块中每个方法的每个注释,然后依次确定是否用Yes or No?yes
Traceback (most recent call last):
File "C:/Users/*user*/Desktop/Code/Python/Nim Game.py", line 5, in <module>
if yesnoA == yes:
NameError: name 'yes' is not defined
注释该注释本身才能看到如果该方法对它有一定的兴趣。这是一个不必要的开销。
可能有更多原因,但这里列出的2个似乎足以让匕首用户使用某种合同:javax.inject.Qualifier
。
注释不会影响代码的性能,并且使用附加注释不会造成任何伤害,因此通过像处理它一样处理它会有更多的损失。