Рейтинг:0

Как предотвратить конфликты похожих пользовательских сервисов?

флаг in

У меня есть два модуля, каждый из которых определяет службу нормализатора.

module_one.services.yml

Сервисы:
  module_one.normalizer.node_entity:
    класс: Drupal\module_one\Normalizer\ModuleOneEntityNormalizer
    аргументы: ['@entity_type.manager']
    теги:
      - {имя: нормализатор, приоритет: 10}

module_two.services.yml

Сервисы:
  module_two.normalizer.node_entity:
    класс: Drupal\module_two\Normalizer\ModuleTwoEntityNormalizer
    аргументы: ['@entity_type.manager']
    теги:
      - {имя: нормализатор, приоритет: 10}

Для каждого модуля я создаю отдельный нормализатор и, предположительно, определяю отдельное пространство имен, например:

<?php

пространство имен Drupal\module_one\Normalizer;

используйте Drupal\Core\Entity\EntityTypeManagerInterface;
используйте Drupal\serialization\Normalizer\ContentEntityNormalizer;
используйте Drupal\node\NodeInterface;

/**
 * Преобразует структуры объектов объектов Drupal в нормализованный массив.
 */
класс ModuleOneEntityNormalizer расширяет ContentEntityNormalizer {
...

Проблема в том, что при включении обоих модулей одна служба блокирует другую — сериализатор/нормализатор срабатывает, как и ожидалось, для первого, но не для второго. Единственный способ распознать другой — повысить его приоритет, но это блокирует первый.

Чего мне не хватает в определениях, которые предотвратили бы конфликт этих двух сервисов друг с другом?

Обновлять: Спасибо за действительно полезные комментарии, начинаю набирать номер по этому поводу. Оба нормализатора имеют один и тот же защищенный $supportedInterface, например:

  /**
   * Интерфейс или класс, который поддерживает этот нормализатор.
   *
   * @var строка
   */
  защищенный $supportedInterfaceOrClass = [
    'Друпал\узел\NodeInterface'
  ];

Который отмечен в Руководство по API сериализации Drupal как проблема

Kevin avatar
флаг in
Почему бы не изменить приоритет, а затем настроить его правила выбора в зависимости от того, когда он применим? https://api.drupal.org/api/drupal/core%21modules%21serialization%21src%21Normalizer%21NormalizerBase.php/function/NormalizerBase%3A%3AsupportsNormalization/9.2.x, если они работают с одними и теми же типами сущностей без условные различия, вам, вероятно, потребуется добавить контекстную информацию при сериализации.
флаг ru
Или, может быть, [служба декоратора] (https://symfony.com/doc/current/service_container/service_decoration.html)
4uk4 avatar
флаг cn
Вам нужно уточнить, что находится в `защищенном $supportedInterfaceOrClass`. Если это то же самое, какой другой параметр, если не приоритет или формат, выбирает, какой нормализатор следует использовать?
Рейтинг:1
флаг in

Found a working answer with the helpful guidance from the comments here. The key is that in both Normalizer classes, I was not using the supportsNormalization function

 /**
 * Checks whether the given class is supported for normalization by this normalizer.
 */
   public function supportsNormalization($data, $format = NULL) {
      if (!is_object($data) || !$this->checkFormat($format)) {
        return FALSE;
      }
      if ($data instanceof NodeInterface && $data->getType() == 'myContentType') {
        return TRUE;
      }
        return FALSE;
      }
    }

With the above function, I can continue to have the priority for both normalizers in the services.yml set to the same value (ex. '10'), it will fire for both but return false if it doesn't match the particular content type.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.