简体   繁体   English

使用 Messenger 作为独立组件将依赖项注入 symfony messenger 可调用处理程序

[英]Inject dependencies into symfony messenger callable handler using Messenger as an independent component

Reading this manual https://symfony.com/doc/current/components/messenger.html#installation阅读本手册https://symfony.com/doc/current/components/messenger.html#installation

I'm trying to integrate Messenger to Slim-based project我正在尝试将 Messenger 集成到基于 Slim 的项目中

Manual handler registration is as simple as callable creation The only thing I can't get is how to inject dependencies anyway How should it be done properly via constructor in case like this手动处理程序注册就像可调用创建一样简单我唯一无法得到的是如何注入依赖项无论如何应该如何通过构造函数正确完成这种情况

namespace App\MessageHandler;

use App\Message\MyMessage;

class MyMessageHandler
{
    private $someRepo;

    public __constructor(SomeRepositoryInterface $someRepo)
    {
       $this->someRepo = $somRepo;
    }

    public function __invoke(MyMessage $message)
    {
        // Message processing...
    }
}

Working example:工作示例:

MessageBusInterface::class => static function (ContainerInterface $container) {
    $sendersMap = [
        EventInterface::class => ['sync://'],
        RedisEventInterface::class => ['message.sender.redis'],
    ];
    $middlewares = [
        $container->get(FailedExceptionMessageMiddleware::class),
        $container->get(MessageLoggerMiddleware::class),
        $container->get(DispatchAfterCurrentBusMiddleware::class),
        new SendMessageMiddleware(
            new SendersLocator(
                $sendersMap,
                $container
            ),
            $container->get(EventDispatcherInterface::class)
        ),
        new HandleMessageMiddleware(
            new EventHandlersLocator(
                $container
            ),
            true
        ),
        new HandleMessageMiddleware(
            new HandlersLocator(
                $container
            ),
            true
        ),
    ];
    return new MessageBus(new SymfonyMessageBus($middlewares));
},
'message.redis.connection' => static function (ContainerInterface $container) {
    /** @var Redis $redis */
    $redis = $container->get(Redis::class);
    return new Connection(
        [
            'stream' => $container->get('CACHE_NAMESPACE'),
            'group' => 'symfony',
            'consumer' => $_ENV['QUEUE_CONSUMER_NAME'] ?? 'consumer',
            'delete_after_ack' => true,
        ],
        ['host' => $container->get('REDIS_HOST'), 'port' => $container->get('REDIS_PORT'),],
        [],
        $redis
    );
},
'sync://' => static function (ContainerInterface $container) {
    return new SyncTransport($container->get(MessageBusInterface::class));
},
'message.sender.redis' => static function (ContainerInterface $container) {
    return new RedisSender(
        $container->get('message.redis.connection'),
        new PhpSerializer()
    );
},
'message.receiver.redis' => static function (ContainerInterface $container) {
    return new RedisReceiver(
        $container->get('message.redis.connection'),
        new PhpSerializer()
    );
},
'retry.strategy.locator' => static function () {
    $builder = new DI\ContainerBuilder();
    $builder->useAutowiring(false);
    $builder->useAnnotations(false);
    $container = $builder->build();
    $container->set(
        'message.receiver.redis',
        static function () {
            // +12sec(1), +1min(2), +5min(3), +25min(4), ...
            return new MultiplierRetryStrategy(1, 12000, 5);
        }
    );

    return $container;
},
'retry.senders.locator' => static function (ContainerInterface $c) {
    $builder = new DI\ContainerBuilder();
    $builder->useAutowiring(false);
    $builder->useAnnotations(false);
    $container = $builder->build();
    $container->set('message.receiver.redis', $c->get('message.sender.redis'));

    return $container;
},
'failure.senders.locator' => static function ($c) {
    $builder = new DI\ContainerBuilder();
    $builder->useAutowiring(false);
    $builder->useAnnotations(false);
    $container = $builder->build();
    $container->set('message.receiver.redis', $c->get(DatabaseSender::class));

    return $container;
},
DatabaseConnectionInterface::class => DI\autowire(DatabaseConnection::class),
RetryStrategyInterface::class => DI\autowire(MultiplierRetryStrategy::class),
EventDispatcherInterface::class => static function (ContainerInterface $container) {
    $dispatcher = new EventDispatcher();
    $dispatcher->addSubscriber(
        new SendFailedMessageForRetryListener(
            $container->get('retry.senders.locator'),
            $container->get('retry.strategy.locator'),
            null,
            $dispatcher
        )
    );
    $dispatcher->addSubscriber(
        new SendFailedMessageToFailureTransportListener(
            $container->get('failure.senders.locator')
        )
    );
    $dispatcher->addSubscriber(
        new AddErrorDetailsStampListener()
    );
    $dispatcher->addSubscriber(
        new StopWorkerOnMessageLimitListener(10)
    );
    $dispatcher->addSubscriber(
        new StopWorkerOnTimeLimitListener(300)
    );
    $dispatcher->addListener(
        WorkerMessageFailedEvent::class,
        function (WorkerMessageFailedEvent $e) use ($container) {
            $handler = $container->get(WorkerMessageFailed::class);
            $handler($e);
        }
    );
    $dispatcher->addListener(
        WorkerMessageHandledEvent::class,
        function (WorkerMessageHandledEvent $e) use ($container) {
            $handler = $container->get(WorkerMessageHandled::class);
            $handler($e);
        }
    );
    $dispatcher->addListener(
        SendMessageToTransportsEvent::class,
        function (SendMessageToTransportsEvent $e) use ($container) {
            $handler = $container->get(SendMessageToTransports::class);
            $handler($e);
        }
    );

    return $dispatcher;
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM