Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
symfony2注入依赖优化_Symfony_Service_Constructor_Dependency Injection_Repository - Fatal编程技术网

symfony2注入依赖优化

symfony2注入依赖优化,symfony,service,constructor,dependency-injection,repository,Symfony,Service,Constructor,Dependency Injection,Repository,我有一个表单事件订阅服务器,它需要一个实体存储库。 我希望在理想情况下注入此存储库依赖项,而不必使用订阅服务器及其父级的构造函数,因为此订阅服务器有许多不同的形式 因此,基本上我有以下链条: 控制器调用->CustomManagerService实例化->表单实例化->EventSubscriber需求->EntityRepository maanager已经是一个服务。将构造器存储库参数从管理器通过表单传输到订阅者是一件痛苦的事情,将每个表单设置为服务也是一件痛苦的事情 为什么我不能直接在订阅

我有一个表单事件订阅服务器,它需要一个实体存储库。 我希望在理想情况下注入此存储库依赖项,而不必使用订阅服务器及其父级的构造函数,因为此订阅服务器有许多不同的形式

因此,基本上我有以下链条:

控制器调用->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));
}
在我的订户中: 受保护的存储库

public function __construct(UnitRepository $unitRepository)
{
$this->unitRepository = $unitRepository;
}
public function preSetData(FormEvent $event)
    {
$unitRepository = $this->unitRepository;
$unitRepository->doStuff()
}
我发现这非常长,有时我有一个表单调用一个子表单,它使用eventSubscriber。如果我将表单设置为服务,有时也会出现错误,因为我在实例化它们时没有使用所需的第一个constructur参数

在知道只有订阅者需要访问存储库的情况下,哪条最短的路径才能正确地完成这一切,并且不重复这一切


非常感谢

我真的不确定自己什么都懂,甚至什么都不懂,但我要试着回答一下

我建议您定义一个服务
SubscriberProvider
,该服务将负责订阅服务器的实例化和在订阅服务器中注入存储库(通过订阅服务器的setter)。您可以使用
get
retrieve
create
provide
或您喜欢的服务
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());

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

您可以向我们展示您的服务定义吗?实例化存储库需要访问实体经理(我假设您使用的是Doctrine 2)。因此,直接在订阅服务器中实例化存储库不会有帮助。如果表单需要注入额外的服务,那么您可以将表单设置为服务。一旦你做了一些,这就足够容易了。您还可以将订阅服务器设置为服务并将其注入表单。@Cerad,那么我需要将表单设置为服务吗?如果我继续像new xxxType()那样在我的管理器中实例化表单而不带参数,我会觉得它会抛出一个错误,不是吗?我已经添加了完整的代码示例。您的解决方案不是在我已经拥有的众多中间层的基础上再增加一个中间层吗?请设置代码以获取提供程序中的存储库。将表单设置为服务。在表单服务中插入提供程序。使用表单中的提供程序获取
AddUnitFieldSubscriber
的实例。这样您就不会有问题了
我有时也会出错,因为我在实例化它们时没有使用所需的第一个constructur参数
。到目前为止,我的表单是使用新的xxxType($This->unitRepository)从自定义管理器类实例化的。如果我将其转换为服务,我需要在控制器中调用并将其作为参数传递,因为在我的manager类中执行new xxxType()不会启动提供程序构造函数参数(“error,provider expected,null gived”)。我说得对吗?然后就像以前一样复杂我给你写了一些代码。请注意,我直接在表单类型中进行工作,因此不需要提供程序。如果我从控制器外部调用表单?我必须将表单作为自定义类的构造函数参数传递,或者在自定义类中实例化表单时,无法找到原则参数。我正在寻找一种方法,使这个订阅服务器不依赖于构造函数参数,因为它被用在许多形式中。