Dagger 2 - 从目标方法提供对象需要实例

问题描述 投票:0回答:1

我需要在匕首2中为TimeStampdeserialize方法提供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。

java dagger-2 json-deserialization dagger
1个回答
0
投票

你在第一个代码示例中使用它的方式是正确的,以及我如何拥有它:你应该调用@Singleton @Provides public Timestamp provideTimestamp() { } ,而不是推迟到Dagger。

你应该绘制的区别是注射剂和新品:注入图中的哪些物体,以及应该用Timestamp创建哪些物体?可能很容易认为每次对new Timestamp(...)的调用都很糟糕,因为它会降低灵活性,但实际情况是它更像是一个判断调用:

  • 如果您想要更改或替换实现,即使在测试中使用测试双打或模拟,那么您的对象应该是可注入的。对于非确定性或昂贵的对象尤其如此,因为您可能希望测试快速且具有确定性。
  • 如果实现是“价值对象”,只是携带结构化数据,那么它们不太可能被替换,并且可能是新的。
  • 如果实现具有很少的依赖性并且易于创建,则它们可能是新的。如果实现将许多服务作为构造函数参数(与许多数据值相对),那么它们应该是可注入的;这是在你的测试中使用假货或嘲笑的一个很好的理由。

另见:MiškoHevery的new


如上所述,Timestamp是一个值对象:您不太可能想要替换实现,Timestamp除了每个实例数据之外没有依赖关系,并且实现非常容易创建。这使得Timestamp成为一个非常好的候选者,成为一个新手。

在你的情况下,你有一个额外的皱纹:你的新时间戳将根据你传入的new对象而变化,并且To “new” or not to “new”…对象将变得足够大,以至于你不太可能想要把它放在你的Dagger图中。这意味着如果您确实想要进行注入而不是注入时间戳,您可能需要注入TimestampFactory,它可以是jsonjson创建的实现,或任何其他实现:

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); } } } 调用。

© www.soinside.com 2019 - 2024. All rights reserved.