Symfony 开发与插件兼容的应用程序的最佳方法。依赖注入?
我想知道创建与插件完全兼容的应用程序的最佳方法 我习惯于Wordpress插件的概念,您可以定义操作和过滤器,然后在插件中使用。因此,其他人可以在其插件上定义在调用操作或过滤器时执行的方法 我的想法是用一些动作和过滤器创建我的应用程序,然后其他开发者可以构建一个干扰正常应用程序流的包 我正在阅读关于Symfony2依赖注入的文章,但是我没有找到一些全面的例子来做类似的事情 有人有一个真实的例子,类似的东西,我正在寻找? 依赖注入是最好的解决方案还是我应该构建自己的插件处理程序? 编辑: 我所做的是允许其他包将项目添加到我的knp菜单 在我的基本包中: 定义允许订阅方获取和设置菜单数据的筛选器:Symfony 开发与插件兼容的应用程序的最佳方法。依赖注入?,symfony,dependency-injection,event-dispatching,pluggable,Symfony,Dependency Injection,Event Dispatching,Pluggable,我想知道创建与插件完全兼容的应用程序的最佳方法 我习惯于Wordpress插件的概念,您可以定义操作和过滤器,然后在插件中使用。因此,其他人可以在其插件上定义在调用操作或过滤器时执行的方法 我的想法是用一些动作和过滤器创建我的应用程序,然后其他开发者可以构建一个干扰正常应用程序流的包 我正在阅读关于Symfony2依赖注入的文章,但是我没有找到一些全面的例子来做类似的事情 有人有一个真实的例子,类似的东西,我正在寻找? 依赖注入是最好的解决方案还是我应该构建自己的插件处理程序? 编辑: 我所做的
# BaseBundle/Event/FilterMenuEvent.php
class FilterMenuEvent extends Event
{
protected $menu;
public function __construct($menu)
{
$this->menu = $menu;
}
public function getMenu()
{
return $this->menu;
}
}
定义菜单的事件:
# Event/MenuEvents.php
final class MenuEvents
{
const BEFORE_ITEMS = 'menu.before.items';
const AFTER_ITEMS = 'menu.after.items';
}
设置订阅服务器:
# Event/MenuSubscriber.php
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array(
array('homeItems', 9000),
array('quickactionsItems', 80),
array('adminItems', 70),
...
array('logoutItems', -9000),
)
);
}
public function homeItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Home', array('route' => 'zashost_zaspanel_homepage'));
}
public function quickactionsItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Quick actions', array( 'route' => null));
$menu['Quick actions']->addChild('Add hosting', array( 'route' => 'zashost_zaspanel_register_host'));
}
}
# services.yml
services:
# Menu items added with event listener
base_menu_subscriber:
class: Acme\BaseBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array('afterItems', 55)
);
}
public function afterItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Backups', array( 'route' => null));
$menu['Backups']->addChild('Create new backup', array( 'route' => null));
return $menu;
}
}
# srevices.yml
services:
menu_subscriber:
class: Acme\ThirdPartyBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
在生成菜单中调度事件:
# Menu\Builder.php
class Builder extends ContainerAware
{
public function userMenu(FactoryInterface $factory, array $options)
{
$menu = $factory->createItem('root');
$this->container->get('event_dispatcher')->dispatch(MenuEvents::AFTER_ITEMS , new FilterMenuEvent($menu));
return $menu;
}
}
将订阅服务器附加到内核事件订阅服务器:
# Event/MenuSubscriber.php
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array(
array('homeItems', 9000),
array('quickactionsItems', 80),
array('adminItems', 70),
...
array('logoutItems', -9000),
)
);
}
public function homeItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Home', array('route' => 'zashost_zaspanel_homepage'));
}
public function quickactionsItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Quick actions', array( 'route' => null));
$menu['Quick actions']->addChild('Add hosting', array( 'route' => 'zashost_zaspanel_register_host'));
}
}
# services.yml
services:
# Menu items added with event listener
base_menu_subscriber:
class: Acme\BaseBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array('afterItems', 55)
);
}
public function afterItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Backups', array( 'route' => null));
$menu['Backups']->addChild('Create new backup', array( 'route' => null));
return $menu;
}
}
# srevices.yml
services:
menu_subscriber:
class: Acme\ThirdPartyBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
然后在第三方包中:
设置我的第三方事件订阅服务器:
# Event/MenuSubscriber.php
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array(
array('homeItems', 9000),
array('quickactionsItems', 80),
array('adminItems', 70),
...
array('logoutItems', -9000),
)
);
}
public function homeItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Home', array('route' => 'zashost_zaspanel_homepage'));
}
public function quickactionsItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Quick actions', array( 'route' => null));
$menu['Quick actions']->addChild('Add hosting', array( 'route' => 'zashost_zaspanel_register_host'));
}
}
# services.yml
services:
# Menu items added with event listener
base_menu_subscriber:
class: Acme\BaseBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array('afterItems', 55)
);
}
public function afterItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Backups', array( 'route' => null));
$menu['Backups']->addChild('Create new backup', array( 'route' => null));
return $menu;
}
}
# srevices.yml
services:
menu_subscriber:
class: Acme\ThirdPartyBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
并附加到内核事件订阅服务器:
# Event/MenuSubscriber.php
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array(
array('homeItems', 9000),
array('quickactionsItems', 80),
array('adminItems', 70),
...
array('logoutItems', -9000),
)
);
}
public function homeItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Home', array('route' => 'zashost_zaspanel_homepage'));
}
public function quickactionsItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Quick actions', array( 'route' => null));
$menu['Quick actions']->addChild('Add hosting', array( 'route' => 'zashost_zaspanel_register_host'));
}
}
# services.yml
services:
# Menu items added with event listener
base_menu_subscriber:
class: Acme\BaseBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
class MenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'menu.after.items' => array('afterItems', 55)
);
}
public function afterItems(FilterMenuEvent $menu_filter)
{
$menu = $menu_filter->getMenu();
$menu->addChild('Backups', array( 'route' => null));
$menu['Backups']->addChild('Create new backup', array( 'route' => null));
return $menu;
}
}
# srevices.yml
services:
menu_subscriber:
class: Acme\ThirdPartyBundle\Event\MenuSubscriber
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
通过这种方式,我可以使用事件调度器的优先级来设置菜单中每组项目的位置。为您的应用程序提供扩展点(其他开发人员可以在其中钩住他们的自定义行为)的一个很好的起点是使用Symfony中的组件,Symfony是 Symfony已经在其自己的核心中广泛使用了该组件,允许其他组件或插件(如果您愿意的话)连接http请求->响应流中的各个点,并处理从请求匹配到响应生成的所有事情 例如,您可以挂接到kernel.request事件并在请求无效时立即返回响应,或者挂接到kernel.Response事件并更改响应内容 请参阅完整的列表 通过使用这些组件,您可以创建一个比Wordpress平台更强大、更可测试、更健壮的插件系统 当然,您可以轻松创建和发送适合您业务逻辑的事件,例如为博客应用程序创建post.created或comment.created等事件 现在,为了举个例子,您将如何配置一个插件,该插件将对生成的响应执行某些操作,然后触发另一个可由另一个插件使用的事件
namespace Vendor;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class ResponseAlter implements EventSubscriberInterface
{
private $dispatcher;
public function __construct(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function doSomethingWithResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
/**
* let other plugins hook to the provide.footer event and
* add the result to the response
*/
$footer = new ProvideFooterEvent();
$this->dispatcher->dispatch('provide.footer', $footer);
$this->addFooterProvidedByPluginToResponse($response, $footer->getProvidedFooter());
$event->setResponse($response);
}
static function getSubscribedEvents()
{
return array(
'kernel.response' => 'doSomethingWithResponse'
);
}
}
现在,您只需以服务订户的身份访问您的服务,就完成了。您刚刚插入了HttpKernel组件:
services:
my_subscriber:
class: Vendor\ResponseAlter
arguments: ['@event_dispatcher']
tags:
- {name: kernel.event_subscriber}
您好,我会更仔细地查看依赖项容器中的标记服务,谢谢Julien,但我认为下面的答案所说的EventDispatcher正是我所寻找的。。