Plugins

Плагин - это абсолютно любой класс, который может быть загружен и использован другими компонентами системы. Поведение плагина описывается контакртами (интерфейсами).

Важное замечание: каждый плагин должен делать только свою конкретную задачу.

Основная цель данного подхода - оставить в сервисном контейнере только те сервисы, которые будут использоваться другими компонентами приложения, и избежать “сервис-хелла” в контейнере.

Пример написания и использовани плагинов

Для начала, давайте создадим контракты будущих плагинов:


interface ExecutorPluginInterface
{
    public function execute(): void;
}

interface AdapterPluginInterface
{
    public function getName(): string;
    public function execute(): void;
}

И имплементируем вышеописанный контракт.

// First plugin
class DefaultAdapterPlugin implements AdapterPluginInterface
{
    public function getName(): string
    {
        return 'default';
    }
    
    public function execute(): void
    {
        print_r(sprintf('Hello, I\'m %s adapter', $this->getName()));
    }
}

// Second plugin
class AdvancedAdapterPlugin implements AdapterPluginInterface
{
    public function getName(): string
    {
        return 'advanced';
    }
    
    public function execute(): void
    {
        print_r(sprintf('Hello, I\'m %s adapter', $this->getName()));
    }
}

После чего добавим еще один плагин, который будет использовать вышеописанные контракты и зарегистрируем его в сервисном контейнере.

use Micro\Framework\Kernel\Plugin\DependencyProviderInterface;
use Micro\Component\DependencyInjection\Container;

// Third plugin
class AdapterExecutor implements DependencyProviderInterface, ExecutorPluginInterface
{
    private KernelInterface $kernel;

    public function provideDependencies(Container $container): void
    {
        $container->register(ExecutorPluginInterface::class, function(
            KernelInterface $kernel
        ) {
            $this->kernel = $kernel;
            
            return $this;
        });
    }
    
    public function execute(): void
    {
        foreach ($this->kernel->plugins(AdapterPluginInterface::class) as $plugin) {
            $plugin->execute();
        }
    }
}

После чего нам необходимо будет зарегистрировать плагины в ядре и запустить приложение. Если вы используете micro/micro, то просто добавьте string-class в etc/plugins.php

  • AdapterExecutor::class
  • AdvancedAdapterPlugin::class
  • DefaultAdapterPlugin::class

После чего плагин AdapterExecutor можно использовать в других компонентах системы через DI/LoC.


$executor = $container->get(ExecutorPluginInterface::class)->execute();
// Hello, I'm default adapter
// Hello, I'm advanced adapter