Можем ли мы провалить сборку для дубликатов IntoSet? - PullRequest
0 голосов
/ 05 июня 2018

Когда мы используем @ IntoSet мультисвязывание и регистрируем несколько одинаковых предметов, тогда Dagger будет использовать один из предметов и молча игнорировать другие.
Есть ли способ настроить кинжал для проверки на наличие дубликатов иСбой сборки?
Или есть обходной путь?

1 Ответ

0 голосов
/ 05 июня 2018

Есть ли способ настроить кинжал для проверки на наличие дубликатов и сбоя сборки?

Нет, это невозможно даже гипотетически, поскольку концепция «дубликатов» зависит от понятия времени выполнения из 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(), вы можете сделать это тоже.

...