Есть ли способ настроить кинжал для проверки на наличие дубликатов и сбоя сборки?
Нет, это невозможно даже гипотетически, поскольку концепция «дубликатов» зависит от понятия времени выполнения из equals
и hashCode
.Даже если возвращаемый объект был точно таким же экземпляром или константой, Dagger может только читать сигнатуры методов во время компиляции, но не код.Он не может определить, возвращают ли отдельные @Provides @IntoSet
методы равные значения или литералы.
Я подозреваю, что сам Даггер также не проверяет во время выполнения;он оставляет проверку на равенство и дедупликацию для реализации Set. Интерфейс Set определяет его поведение там.
Почему вы хотите зарегистрировать несколько элементов, а затем использовать только случайный из них?
Вы правы, что поведение должно быть детерминированным , а не случайным или произвольным , что является частью причины, по которой вы можете получить Set (неупорядоченный), ноне список (заказано).Вы называете вывод случайным, но только потому, что вы различаете два объекта, которые объявляют себя equal
друг другу.Если мы с другом разделим две пятидолларовые купюры, я не считаю результат случайным или недетерминированным при условии, что он и я согласны, что купюры равны друг другу.
Что касается Java,у вас есть две копии одного и того же объекта .Это может иметь смысл, если вам нужен интерфейс плагина, где ModuleA устанавливает @Binds @IntoSet Plugin bindFooPlugin(FooPlugin foo);
, а ModuleB устанавливает @Binds @IntoSet Plugin bindFooPlugin(FooPlugin foo);
.Хотя вы могли бы привести хороший аргумент в пользу идеального поведения в любом случае, я ожидал бы, что FooPlugin будет в Set<Plugin>
ровно один раз, если его реализация equals
не указывает на то, что экземпляры плагинов отличаются друг от друга, и в этом случае я быожидайте по одному на привязку @IntoSet.
Что касается обходных путей, вы можете:
Настроить реализацию equals
. You 'Вы видите это поведение, потому что два объекта равны.Если вы не хотите, чтобы они были равны, надеюсь, это код, которым вы сможете управлять.
Оберните объект ради equals
. Это делает Гуавадо Equivalence.identity().wrap(obj)
, что требует ряда дополнительных экземпляров, но позволяет переопределить концепцию внутреннего объекта equals
.
Использовать множественные привязкиКарта. В отличие от возвращаемых значений из @IntoSet или @IntoMap, Даггер настаивает на том, чтобы ключи карты были константами времени компиляции , определенными как аннотации, которые имеют строгое определение равенства, которое можно проверитьво время компиляции .Хотя вы не можете использовать здесь свои собственные объекты, Dagger ломается во время компиляции для дубликатов ключей карты :
StringBuilder message =
new StringBuilder("The same map key is bound more than once for ")
.append(mapBindingKey);
Конечно, если вы хотите использовать эту карту ивернуть набор значений с проверкой на дублирование через Map.values()
, вы можете сделать это тоже.