मेरे पास एक वर्ग पथ है जो नियमित पथ का प्रतिनिधित्व करता है और इसके साथ कुछ जादू सामग्री कर सकता है। जब भी मैं अपने ऐप में पथों से निपटना चाहता हूं, मैं पथ ऑब्जेक्ट को तुरंत चालू करना चाहता हूं और इसके साथ काम करना जारी रखना चाहता हूं। पथ वर्ग में कुछ निर्भरताएं हैं और मैं ऑटोवॉयरिंग/निर्भरता इंजेक्शन का उपयोग करना चाहता हूं।

मैंने क्या प्रयास किया:

मेरे पास एक सेवा के रूप में कक्षा है और एक फ़ैक्टरी विधि बनाई है, जैसा कि यहाँ वर्णित है: https://symfony.com/doc/current/service_container/factories.html। फ़ैक्टरी विधि निर्भरता को तर्क के रूप में प्राप्त करती है और उन्हें निजी विशेषताओं में संग्रहीत करती है। जहां भी मुझे एक उदाहरण की आवश्यकता होती है, मैं केवल एक निर्भरता इंजेक्शन का उपयोग करके नए उदाहरण प्राप्त करने में सक्षम था। यहां निर्भरता के साथ कोई समस्या नहीं है। अब समस्या यह है कि मैं निर्भरता इंजेक्शन का उपयोग करके केवल एक उदाहरण प्राप्त कर सकता हूं। हां, मैं एक ओवर में "सादे" वस्तु का क्लोन बना सकता हूं, लेकिन मुझे लगता है कि एक बेहतर समाधान है। फैक्ट्री विधि को हाथ से कॉल करना वहां निर्भरता इंजेक्शन की वजह से काम नहीं करता है।

सेवा और नियंत्रक:

<?
// Service
namespace App\Service;

class Path {
    private $dep;

    public function __construct(DependencyName $dep) {
        $this->dep = $dep;
    }

    public static function factory(DependencyName $dep) {
        $path = new Path($dep);
        return $path;
    }

    // some methods
}

// Controller
namespace App\Controller;

use App\Service\Path;

class SomeController {
    public function generatePaths() {
        for (int i = 0; i < 10; i++) {
            $paths[] = Path::factory(/* missing dependencies */);
        }
    }

    public function __construct(Path $path) {
        // here I can have one Path without a problem
        // but I need more than one
    }
}

Services.yaml में:

App\Service\Path:
        # call the static method
        factory: ['App\Service\Path', 'factory']

अधिक सामान्य: जब मैं ऑटोवायरिंग का उपयोग करता हूं, तो मैं एक सेवा के कई उदाहरण कैसे बना सकता हूं जिसमें निर्भरता है? समाधान नियंत्रकों तक सीमित नहीं होना चाहिए। मुझे इस सेवा का उपयोग अन्य सेवाओं में भी करने की आवश्यकता है।

3
askuri 25 जुलाई 2019, 17:52

1 उत्तर

सबसे बढ़िया उत्तर

आप अपनी सेवा परिभाषा में shared विकल्प का उपयोग कर सकते हैं:

सर्विस कंटेनर में, सभी सेवाएँ डिफ़ॉल्ट रूप से साझा की जाती हैं। इसका मतलब है कि [...] आपको वही उदाहरण मिलेगा। कुछ मामलों में, आप हमेशा एक नया उदाहरण प्राप्त करना चाह सकते हैं।

ऐसा करने से (जैसा कि मैं समझता हूं कि आपका Dependency हमेशा एक जैसा होता है) आपको अब factory विधि की आवश्यकता नहीं होगी और आप इसकी परिभाषा को बदल सकते हैं:

App\Service\Path:
        class: App\Service\Path
        shared: false

एक से अधिक इंस्टेंस होने के लिए आप इंजेक्शन का उपयोग नहीं कर सकते हैं, इसलिए आपको ServiceSubscriberInterface और अपनी सेवा को पंजीकृत करें ताकि आप ऑटोवायरिंग का लाभ उठाते हुए हर बार जरूरत पड़ने पर इसे कंटेनर से मैन्युअल रूप से प्राप्त कर सकें।

मैं अधिक विस्तार में नहीं जाऊंगा, क्योंकि कई विकल्प हैं और कोई दूसरों की तुलना में अधिक समझ में आता है, लेकिन एक बार लागू होने के बाद:

$path = $this->get('path_builder'); // Whatever your alias is

हर बार आपको एक नया उदाहरण मिलेगा।

2
msg 26 जुलाई 2019, 01:56