symfony एक बंडल द्वारा गतिशील रूप से बनाए गए किसी सेवा पर एक विधि कॉल करें




service dependency-injection (3)

मैं कई एचटीटीपी ग्राहकों को पंजीकृत करने के लिए m6web_guzzle बंडल का उपयोग कर रहा हूं:

m6web_guzzlehttp:
    clients:
        myclient:
            timeout: 3
            headers:
                "Accept": "application/json"
            delay: 0
            verify: false

मैं उस सेवा पर एक विधि कॉल करना चाहता हूं जो इसे गतिशील रूप से उत्पन्न करती है इस मामले में उत्पन्न सेवा नाम है:

@m6web_guzzlehttp.guzzle.handlerstack.myclient

मेरी सर्विस कन्स्ट्रक्टर में मैं यही करता हूं: (इंजेक्शन वाला तीसरा पैरामीटर है '@ एम 6 वीब_गॉशन .http.guzzle.handlerstack.myclient')

/**
 * @param array        $parameters
 * @param Client       $client
 * @param HandlerStack $handlerStack
 */
public function __construct(array $parameters, Client $client, HandlerStack $handlerStack)
{
    $this->parameters = $parameters;
    $this->client = $client;
    $this->handlerStack->push(Middleware::retry([$this, 'retryDecider']));
}

अब तक, यह अच्छी तरह से काम करता है, लेकिन मैं अपनी services.yml आईएमएल फाइल में अंतिम पंक्ति ( push कॉल) को कैसे स्थानांतरित कर सकता हूं? या फिर इस पुनः प्रयास करने वाले को पंजीकृत करने के लिए एक और क्लीनर विधि?

https://code.i-harness.com


आप एक संकलक पास लिख सकते हैं जो प्रश्न में परिभाषा को पकड़ लेता है और इसके लिए विधि कॉल जोड़ता है।


इसलिए कंपाइलर पास का उल्लेख पहले किया गया था यह एक विकल्प है

उदाहरण बनाने के लिए कारखानों का उपयोग करें

लेकिन आप अपनी सेवाओं की परिभाषा में इसे सीधे भी व्यक्त कर सकते हैं। मैं लगभग कहता हूं, क्योंकि सिमफोनी सेवा की परिभाषाएं (एएफएआईके) एक क्लोजर का मूल्यांकन नहीं कर सकती हैं क्योंकि आपको कुछ प्रकार की कोड की आवश्यकता होगी - जो कि हम गज़ले मिडलवेयर के लिए आवश्यक हैं

मैंने एक उदाहरण के रूप में इस services.yml को लिखा है:

m6web_guzzlehttp.guzzle.handlerstack.myclient:
    class: GuzzleHttp\HandlerStack
    factory: ['GuzzleHttp\HandlerStack', create]

retry_decider:
    class: MyBundle\RetryDecider
    factory: ['MyBundle\RetryDecider', createInstance]

retry_handler:
    class: GuzzleHttp\Middleware
    factory: ['GuzzleHttp\Middleware', retry]
    arguments:
        - '@retry_decider'

handlerstack_pushed:
    parent: m6web_guzzlehttp.guzzle.handlerstack.myclient
    calls:
        - [push, ['@retry_handler']]

कौन सा क्या है?

  • m6web_guzzlehttp.guzzle.handlerstack.myclient - आपकी गतिशील सेवा - उदाहरण से निकालें क्योंकि आपने यह पहले से ही बनाया है।
  • retry_decider - आपका निर्णायक हम createInstance विधि में एक बंद वापसी यदि आप की जरूरत है तो आप अधिक पैरामीटर जोड़ सकते हैं, बस अपने YML में तर्क जोड़ें
  • retry_handler - यहाँ हम मिडलवेयर को हमारे decider का उपयोग करते हुए तैयार करते हैं
  • handlerstack_pushed - यहां हम push() हमारे माता-पिता सेवा के रूप में गतिशील सेवा का उपयोग करके push() स्टैक में हैंडलर को दबाते हैं।

एट वॉइला - हमारे पास स्टैक है जो गतिशील सेवा को परिभाषित करता है, लेकिन हमारी रीट्री मिडलवेयर को धक्का दिया।

हमारे निर्णायक के लिए यहां स्रोत है:

<?php

namespace MyBundle;

class RetryDecider {

    public static function createInstance() {
        return function() {
            // do your deciding here
        };
    }

}

-> अब आपके पास सेवा handlerstack_pushed जो पूर्ण स्टैक है।

अधिक कॉन्फ़िगर करना

कृपया ध्यान दें कि आप m6web_guzzlehttp.guzzle.handlerstack.myclient को parameters.yml जोड़ सकते हैं:

parameters:
    baseHandlerStackService: m6web_guzzlehttp.guzzle.handlerstack.myclient

तो उस पर handlerstack_pushed पर उपयोग करें:

handlerstack_pushed:
    parent: "%baseHandlerStackService%"
    calls:
        - [push, ['@retry_handler']]

बस उस तरह अच्छे ;-)


आपके बंडल की Extension.php फ़ाइल में, आप लोड विधि ओवरराइड कर सकते हैं और जोड़ सकते हैं:

$definition = $container->getDefinition('m6web_guzzlehttp.guzzle.handlerstack.myclient');
$definition->addMethodCall('push', [Middleware::retry([$this, 'retryDecider'])]);




yaml