Правильно, как у вас в первом примере кода, и как у меня это получилось: вы должны звонить new Timestamp(...)
, а не откладывать Dagger.
Различие, которое вы должны рисовать: injectables vs newables : Какие объекты в вашем графике следует вводить и какие объекты следует создавать с помощью new
? Может быть соблазнительно думать, что каждый вызов new
плох, потому что он снижает гибкость, но реальность такова, что это скорее суждение:
- Если вы когда-нибудь захотите изменить или заменить реализацию, даже используя тестовые двойники или макеты в тестах, тогда ваш объект должен быть инъецируемый . Это особенно верно для недетерминированных или дорогих объектов, потому что вы, вероятно, хотите, чтобы ваши тесты были быстрыми и детерминированными.
- Если реализации являются «объектами значений», которые делают немного больше, чем носят структурированные данные, то они вряд ли будут заменены и, вероятно, newable .
- Если реализации имеют мало зависимостей и их легко создать, они могут быть newable . Если реализации принимают множество сервисов в качестве параметров конструктора (в отличие от многих значений данных), то они, вероятно, должны быть injectable ; это было бы хорошей причиной для использования подделок или насмешек в ваших тестах.
См. Также: «Новым» или не «новым»… , автор Miško Hevery
Как упомянуто выше, Timestamp является объектом-значением: маловероятно, что вы когда-либо захотите заменить реализацию, Timestamp не имеет никаких зависимостей, кроме данных для каждого экземпляра, а реализации очень легко создать. Это делает Timestamp чрезвычайно хорошим кандидатом на newable .
В вашем случае у вас есть дополнительная складка: ваша новая временная метка будет меняться в зависимости от объекта json
, который вы передаете, а объект json
будет меняться настолько, что вряд ли вы захотите положить его в свой график кинжала. Это означает, что если вы захотели продолжить внедрение, а не вводить метку времени, вам, вероятно, нужно внедрить TimestampFactory, которая может быть ссылкой на конструктор , Автозаводом -созданная реализация или любая другая реализация:
interface TimestampFactory {
Timestamp create(long value);
}
Это кажется чрезмерным, но давайте представим , вместо этого вам понадобится Timestamp2, который также записывает текущее время дня и, следовательно, может затруднить тестирование. В этом случае вы можете ввести свою фабрику временных меток :
@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);
}
}
}
Это позволит вам вызвать provideJsonDeserializer
в ваших тестах и передать выбранную вами TimestampFactory, например, такую, которая использует поддельное системное время вместо реального. Это позволит сделать ваши тесты намного безопаснее и более детерминированными.
Однако, поскольку вам нужна быстрая метка времени объекта с определенным значением, которая не имеет внешних зависимостей, таких как службы RPC, доступ к файловой системе или фактическое системное время, оставьте вызов new Timestamp
таким же, как в вашем вопросе.