2015-04-22 2 views
2

Есть ли возможность построить цепочку переопределения связки в Symfony2?Цепочка привязки/обслуживания в Symfony2?

Например, в ядре продукта имеется CoreFeatureX. И есть два плагина, расширяющие эту функцию PluginA и PluginB.

Использование стандартных методов из here или из here плагины могут отменять CoreFeatureX проблем. Но только один из них одновременно может это сделать.

Есть ли возможность автоматически строить переопределения цепи так, что если оба PluginA и PluginB, зарегистрированный в системе, они могут и продлить CoreFeatureX (может быть, наследуя друг от друга автоматически), но не знать друг о друге?

Аналогичная технология расширения используется, например, системой форума XenForo. XenForo создает цепочку наследования из плагинов, которые были зарегистрированы как некоторые расширения основного класса. Затем он предоставляет самый верхний класс расширительной цепи как самого этого основного класса.

+0

Я хорошо понимаю вас, что вы хотите зарегистрировать пучки 'CoreFeatureX',' PluginA', 'PluginB', где плагины предназначены для расширения' CoreFeatureX' напрямую, но в результате получают цепочку наследования цепей типа «CoreFeatureX» 'расширенный' PluginA', расширенный 'PluginB'? –

+0

@dragoste Точно. Точный порядок расширения неважен. Это может быть «CoreFeatureX», расширенный «PluginB», расширенный «PluginA», например. Но для «PluginA» и «PluginB» требуется расширение «CoreFeatureX» и не знать друг о друге. –

+0

Я думаю, что это будет лучше, если вы добавите код sudo –

ответ

0

Поскольку Symfony2 не позволяет нам распространять один и тот же комплект одновременно в одно и то же время, вы не можете этого сделать в «чистом» Symfony2.

Это четко реализуется в Symfony\Component\HttpKernel\Kernel::initializeBundles() здесь:

protected function initializeBundles() 
{ 
    // (...) 

    foreach ($this->registerBundles() as $bundle) { 
     //(...) 
     if ($parentName = $bundle->getParent()) { 
      if (isset($directChildren[$parentName])) { 
       throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); 
      } 
      //(...) 
      $directChildren[$parentName] = $name; 
     } else { 
      $topMostBundles[$name] = $bundle; 
     } 
    } 

    //(...) 
} 

Я предполагаю, что это по причине. В любом случае вы можете попытаться переопределить поведение класса метода initializeBundles (в классе AppKernel). В строке, где исключение указано выше, если вы выбросили, вы можете изменить родительский пакет от CoreFeatureX до последнего в цепочке.

В случае PluginB сменить родительский комплект на PluginA, поскольку он уже распространяется CoreFeatureX.

В случае PluginC сменить родительский комплект на PluginB, поскольку он находится на конце текущей цепи наследования.

Я не знаю, смогло ли это работать, это всего лишь идея. Во всяком случае, это был бы интересный эксперимент. ;-)

Редактировать. Я просто notined в свой комментарий на вопрос, который вы писали:

Но требование для обоих Плугина и PluginB расширить CoreFeatureX и быть не знают друг друга.

Что ж, здесь что-то не так. Как вы хотите переопределить один плагин вторым и с другой стороны, чтобы они не знали друг о друге? Не имеет смысла для меня.

+0

Спасибо за ответ. О расширении - они должны расширять «CoreFeatureX». Если они расширяют друг друга - это следует рассматривать как детали реализации и заботиться о структуре. Этого можно достичь, используя классы Proxy, например, для прозрачного наследования. –

+0

Вы сказали, что хотите достичь ** цепи **. Теперь вы говорите, что они должны расширять «CoreFeatureX». Я теперь смущен тем, чего вы пытаетесь достичь. –

+0

Прошу прощения за то, что непонятно. Еще раз: я хочу создать систему плагинов, где плагины могут самостоятельно расширять основные функции. XenForo делает это, создавая цепочку наследования, которая позволяет моделировать некоторые особенности Aspect Oriented Programming вокруг ваших основных классов. Что может предложить Symfony? При использовании технологий расширения по умолчанию только один пакет одновременно может расширить некоторые основные объекты. –

Смежные вопросы