我需要在匕首2中为TimeStamp
的deserialize
方法提供JsonDeserializer
。
@Singleton
@Provides
public JsonDeserializer provideJsonDeserializer() {
return new JsonDeserializer() {
public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new Timestamp(json.getAsJsonPrimitive().getAsLong());
}
};
}
但是这个对象需要来自qazxsw poi的qazxsw poi对象。我怎样才能将这个对象传递给我的JsonElement
方法。
JsonDeserializer
或者我应该不通过匕首注射provideTimestamp
,如果是这样的话可以解释为什么,这可能会帮助我更多地了解匕首2。
你在第一个代码示例中使用它的方式是正确的,以及我如何拥有它:你应该调用@Singleton
@Provides
public Timestamp provideTimestamp() {
}
,而不是推迟到Dagger。
你应该绘制的区别是注射剂和新品:注入图中的哪些物体,以及应该用Timestamp
创建哪些物体?可能很容易认为每次对new Timestamp(...)
的调用都很糟糕,因为它会降低灵活性,但实际情况是它更像是一个判断调用:
另见:MiškoHevery的new
如上所述,Timestamp是一个值对象:您不太可能想要替换实现,Timestamp除了每个实例数据之外没有依赖关系,并且实现非常容易创建。这使得Timestamp成为一个非常好的候选者,成为一个新手。
在你的情况下,你有一个额外的皱纹:你的新时间戳将根据你传入的new
对象而变化,并且To “new” or not to “new”…对象将变得足够大,以至于你不太可能想要把它放在你的Dagger图中。这意味着如果您确实想要进行注入而不是注入时间戳,您可能需要注入TimestampFactory,它可以是json
,json
创建的实现,或任何其他实现:
constructor reference
这似乎过多,但让我们假装你想要Timestamp2,它也会记录当前的时间,因此可能会使测试变得困难。在这种情况下,您可以注入时间戳工厂:
AutoFactory
这将允许您在测试中调用interface TimestampFactory {
Timestamp create(long value);
}
并传入您选择的TimestampFactory,例如使用假系统时间而不是真实时间的那个。这将使您的测试更安全,更具确定性。
但是,由于您需要快速,确定性的值对象Timestamp,它不具有RPC服务,文件系统访问或实际系统时间等外部依赖关系,因此请在问题中保留@Singleton
@Provides
public JsonDeserializer provideJsonDeserializer(Timestamp2Factory tsFactory) {
return new JsonDeserializer() {
public Timestamp2 deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
return tsFactory.create(json.getAsJsonPrimitive().getAsLong());
}
};
}
@Reusable
@Provides
public Timestamp2Factory provideTimestamp2Factory() {
// Merge in other parameters and dependencies if needed,
// but Timestamp2 only needs one value that create(long) supplies.
return Timestamp2::new;
// or, pre-Java-8:
return new Timestamp2Factory() {
@Override public Timestamp2 create(long time) {
return new Timestamp2(time);
}
}
}
调用。