Плагин - это абсолютно любой класс, который может быть загружен и использован другими компонентами системы. Поведение плагина описывается контакртами (интерфейсами).
Важное замечание: каждый плагин должен делать только свою конкретную задачу.
Основная цель данного подхода - оставить в сервисном контейнере только те сервисы, которые будут использоваться другими компонентами приложения, и избежать “сервис-хелла” в контейнере.
Пример написания и использовани плагинов
Для начала, давайте создадим контракты будущих плагинов:
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