symfony2注入依赖优化

时间:2014-11-29 10:41:15

标签: symfony service constructor dependency-injection repository

我有一个表单事件订阅者需要一个实体存储库。 我想在理想情况下注入这个存储库依赖,而不必使用订阅者及其父节点的构造函数,因为需要许多不同形式的订阅者。

所以基本上我有以下链:

控制器通话 - > CustomManagerService实例化 - >表单实例化 - > EventSubscriber需要 - > EntityRepository

maanager已经是一项服务。将构造函数存储库参数从管理器通过表单传递给订阅者是一件痛苦的事情,将每个表单设置为服务是一件痛苦的事。

为什么我不能直接在订阅者中实例化存储库?我读过这是一个不好的做法。

编辑:这是我到目前为止所做的:

在我的控制器中:

$unitRepository = $this->getDoctrine()->getRepository('UnitRepository');
$myManager = $this->get('my_manager')
$form = $myManager->createForm($unitRepository);
在myManager中

public function createForm(UnitRepository $unitRepository){
return $this->formFactory->createForm(
new xxxType($unitRepository)
}

以我的形式:

use MyBundle/AddUnitFieldSubscriber;
protected $unitRepository;

public function __construct(UnitRepository $unitRepository)
{
$this->unitRepository = $unitRepository;
}

public function buildform()
{
$builder->addEventSubscriber(new AddUnitFieldSubscriber($this->unitRepository));
}

在我的订阅者中:     protected $ unitRepository;

public function __construct(UnitRepository $unitRepository)
{
$this->unitRepository = $unitRepository;
}
public function preSetData(FormEvent $event)
    {
$unitRepository = $this->unitRepository;
$unitRepository->doStuff()
}

我发现这非常长,有时我有一个表单调用子表单,使用eventSubscriber。如果我将表单设置为服务,我有时也会得到错误,因为我在没有所需的第一个constructur参数的情况下实例化它们。

做正确的最短路径是什么,不重复所有这些只知道订阅者需要访问存储库?

非常感谢!

1 个答案:

答案 0 :(得分:0)

我真的不确定我是否了解所有内容甚至是什么,但我会尝试回复。

我建议你定义一个服务SubscriberProvider,它将负责订户的实例化和订户中存储库的注入(通过订户的设置者)。您可以使用方法getretrievecreateprovide或您喜欢的服务SubscriberProvider来检索订阅者的实例。然后,您可以在另一项服务中注入此提供程序。

修改

以下是与表单类型相关的服务定义:

services:
    your_own_bundle.form.type.unit:
        class: Your\OwnBundle\Form\Type\UnitType
        arguments:
            - "@doctrine"
        tags:
            - { name: form.type, alias: unit }

及其班级:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\Common\Persistence\ManagerRegistry;
use Your\OwnBundle\Event\AddUnitFieldSubscriber;

class UnitType extends AbstractType
{
    protected $unitRepository;

    public function __construct(ManagerRegistry $doctrine)
    {
        $this->unitRepository = $doctrine->getRepository('UnitRepository');
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addEventSubscriber(
            new AddUnitFieldSubscriber($this->unitRepository)
        );
    }

然后,你可以像这样使用这种类型:

$builder->add('available_unit', 'unit', array());

这样,您就不必将存储库传递给您的经理。