Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/281.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
Php symfony2中的装饰器和依赖项注入_Php_Oop_Symfony_Dependency Injection - Fatal编程技术网

Php symfony2中的装饰器和依赖项注入

Php symfony2中的装饰器和依赖项注入,php,oop,symfony,dependency-injection,Php,Oop,Symfony,Dependency Injection,例如,我有一些界面: interface ISmsRepository { public function send(SmsMessage $sms); } 我有这个类的实现: class SmsRepository implements ISmsRepository{/**some implementation*/} 现在我想实现SmsRepository类的装饰器: class QueueSmsRepository implements ISmsRepository{

例如,我有一些界面:

interface ISmsRepository {
    public function send(SmsMessage $sms);
} 
我有这个类的实现:

class SmsRepository implements ISmsRepository{/**some implementation*/}
现在我想实现SmsRepository类的装饰器:

class QueueSmsRepository implements ISmsRepository{
    /**
     * @var ISmsRepository
     */
    private $smsRepository;

    public function __construct(ISmsRepository $repository) {
        $this->smsRepository = $repository;
    }

    public function send(SmsMessage $sms) {
        //some addable actions
        $this->smsRepository->send($sms);
    }
}
我能找到不止一个装饰师。我如何在配置中描述它?我试着这样做:

<service id="manyrus.sms_bundle.decorated.epochta.sms_repository"
             class="Manyrus\SmsBundle\Lib\Decorators\QueueSmsRepository">
        <argument type="service" id="manyrus.sms_bundle.decorated.epochta.sms_repository"/>
</service>

但我有一个错误:

检测到服务“manyrus.sms_bundle.decorated.epochta.sms_repository”路径的循环引用:“manyrus.sms_bundle.decorated.epochta.sms_repository->manyrus.sms_bundle.decorated.epochta.sms_repository”


我不知道该怎么办。现在,我看到这种情况只有一个出路——创建服务,它将装饰我的SmsRepository。你有什么想法吗?

你必须手动修改一些定义。您可以直接在扩展文件中执行此操作,但如果希望其他捆绑包能够添加装饰器,我建议您使用:

// ../DependencyInjection/Compiler/DecorateSmsRepository.php    

namespace Manyrus\SmsBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;

class DecorateSmsRepository implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $repositoryId = 'manyrus.sms_bundle.decorated.epochta.sms_repository';

        if (!$container->hasDefinition($repositoryId)) {
            return;
        }

        $definition = $container->getDefinition($repositoryId);

        // Retrieve the ids of the services tagged with "manyrus.sms_bundle.sms_repository.decorator".
        $taggedServices = $container->findTaggedServiceIds(
            'manyrus.sms_bundle.sms_repository.decorator'
        );

        foreach ($taggedServices as $id => $attributes) {
            // Replace the first argument passed to the constructor by the decorator.
            $definition->replaceArgument(0, new Reference($id));

            // Chain the decorator mechanism.
            $definition = $container->getDefinition($id);
            $repositoryId = $id;
        }

        // Set an alias on the last decorator (this will be the service you want to use).
        $container->setAlias(
            'manyrus.sms_bundle.decorated.epochta.decorated_sms_repository',
            new Alias($repositoryId, false)
        );
    }
}
您的服务定义应为:

<service id="manyrus.sms_bundle.decorated.epochta.sms_repository"
         class="Manyrus\SmsBundle\Lib\SmsRepository">
    <argument />
</service>

<service id="manyrus.sms_bundle.decorated.epochta.sms_repository.decorator.queue"
         class="Manyrus\SmsBundle\Lib\Decorators\QueueSmsRepository">
    <argument />
    <tag name="manyrus.sms_bundle.sms_repository.decorator" />
</service>
然后,您可以使用服务
manyrus.sms\u bundle.definated.epochta.definated\u sms\u存储库

您可以使用,无需使用编译器密码

<service id="manyrus_decorated"
         class="Manyrus\SmsBundle\Lib\SmsRepository">
    <argument />
</service>

<service id="manyrus_decorator" class="Manyrus\SmsBundle\Lib\Decorators\QueueSmsRepository" decorates="manyrus_decorated" public="false">
    <argument type="service" id="manyrus_decorator.inner" />
</service>

您正在将服务注入it本身。你应该注入另一个短信服务来装饰它们。别忘了在什么时候回答你的问题。
<service id="manyrus_decorated"
         class="Manyrus\SmsBundle\Lib\SmsRepository">
    <argument />
</service>

<service id="manyrus_decorator" class="Manyrus\SmsBundle\Lib\Decorators\QueueSmsRepository" decorates="manyrus_decorated" public="false">
    <argument type="service" id="manyrus_decorator.inner" />
</service>
manyrus_decorated