कुछ वर्ग अपने निर्माता और di.xml दोनों में इंजेक्शन को क्यों परिभाषित करते हैं?


12

मुझे समझ में नहीं आता है, कुछ वर्गों में, उनके निर्भरता इंजेक्शन को दो बार घोषित किया जाता है - एक बार di.xmlऔर ठोस वर्ग के निर्माता में।

उदाहरण के लिए Magento\Backend\Model\Url, इसके di.xmlडि के लिए इस प्रकार के सेट को परिभाषित किया गया है:

<type name="Magento\Backend\Model\Url">
    <arguments>
        <argument name="scopeResolver" xsi:type="object">
Magento\Backend\Model\Url\ScopeResolver</argument>
        <argument name="authSession" xsi:type="object">
Magento\Backend\Model\Auth\Session\Proxy</argument>
        <argument name="formKey" xsi:type="object">
Magento\Framework\Data\Form\FormKey\Proxy</argument>
        <argument name="scopeType" xsi:type="const">
Magento\Store\Model\ScopeInterface::SCOPE_STORE </argument>
        <argument name="backendHelper" xsi:type="object">
Magento\Backend\Helper\Data\Proxy</argument>
    </arguments>
</type>

लेकिन एक ही समय में, अपने ठोस वर्ग में, इंजेक्शन के लिए आवश्यक di.xml में परिभाषित उन वर्गों को फिर से कंस्ट्रक्टर में फिर से घोषित किया गया है:

<?php
    public function __construct(
        \Magento\Framework\App\Route\ConfigInterface $routeConfig,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
        \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
        \Magento\Framework\Session\Generic $session,
        \Magento\Framework\Session\SidResolverInterface $sidResolver,
        \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
        \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        $scopeType,
        \Magento\Backend\Helper\Data $backendHelper,
        \Magento\Backend\Model\Menu\Config $menuConfig,
        \Magento\Framework\App\CacheInterface $cache,
        \Magento\Backend\Model\Auth\Session $authSession,
        \Magento\Framework\Encryption\EncryptorInterface $encryptor,
        \Magento\Store\Model\StoreFactory $storeFactory,
        \Magento\Framework\Data\Form\FormKey $formKey,
        array $data = []
) {
    //...
}
?>

यदि हम इसके निर्माणकर्ता को ऊपर देखते हैं, \Magento\Framework\App\Route\ConfigInterface $routeConfigउदाहरण के लिए, में परिभाषित नहीं किया गया है di.xml। यह केवल कंस्ट्रक्टर में परिभाषित किया गया है और Magento अभी भी उपयोग के routeConfigलिए कक्षा में इंजेक्ट करेगा, है ना? उसी के लिए \Magento\Framework\Encryption\EncryptorInterface $encryptorऔर कुछ अन्य।

फिर, di.xmlजब निर्माणकर्ता उन घोषणाओं को उपयोग के लिए वर्ग में शामिल करने के लिए मैगेंटो के लिए पर्याप्त है, तो निर्माणकर्ता में दोनों में और निर्माणकर्ता में अन्य इंजेक्शनों को परिभाषित करने की आवश्यकता क्यों है ?

जवाबों:


15

दस्तावेज़ में कहा गया है , Magento 2 में, di.xmlनिम्नलिखित करने के लिए इस्तेमाल किया जा सकता है:

आप वर्ग di.xmlनोड में अपने तर्क में वर्ग कंस्ट्रक्टर को कॉन्फ़िगर कर सकते हैं । ऑब्जेक्ट मैनेजर निर्माण के दौरान इन तर्कों को कक्षा में इंजेक्ट करता है। एक्सएमएल फ़ाइल में कॉन्फ़िगर किए गए तर्क का नाम कॉन्फ़िगर वर्ग में कंस्ट्रक्टर में पैरामीटर के नाम के अनुरूप होना चाहिए।

आपके मामले में यह थोड़ा जटिल है मैं प्रत्येक तर्क को एक-एक करके समझाने जा रहा हूँ:

  • \Magento\Framework\App\Route\ConfigInterface $routeConfig: यह एक इंटरफ़ेस है इसलिए यह सीधे प्रयोग करने योग्य नहीं है । इस वर्ग के लिए वरीयता में परिभाषित किया गया हैapp/etc/di.xml और यह है Magento\Framework\App\Route\Configवर्ग
  • \Magento\Framework\App\RequestInterface $request : वही इस वर्ग के लिए जाता है, वरीयता है Magento\Framework\App\Request\Http
  • \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo: Magento\Framework\Url\SecurityInfo\Proxyवरीयता के रूप में एक ही मामला यहाँ फिर से
  • \Magento\Framework\Url\ScopeResolverInterface $scopeResolver: यहाँ हम दिलचस्प बिट के साथ शुरू करते हैं। में app/etc/di.xmlएक प्राथमिकता इस इंटरफेस के लिए परिभाषित किया गया है और यह है Magento\Framework\Url\ScopeResolverवर्ग। हालांकि, Magento\Backend\Model\UrlMagento 2 के लिए एक और वर्ग का उपयोग करने की आवश्यकता है और इस प्रकार यह परिभाषित करता है कि di.xmlआपके द्वारा पोस्ट की गई कौन सी कक्षा का Magento\Backend\Model\Url\ScopeResolverउपयोग किया जाएगा।
  • \Magento\Framework\Session\Generic $session यह एक सामान्य वर्ग है और इस प्रकार इसका उपयोग किया जा सकता है।
  • \Magento\Framework\Session\SidResolverInterface $sidResolver: एक इंटरफ़ेस पर वापस, वरीयता अभी भी परिभाषित है app/etc/di.xmlऔर यह हैMagento\Framework\Session\SidResolver\Proxy
  • \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory : यह एक कारखाना वर्ग है इसलिए इसका उपयोग किया जा सकता है।
  • \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver: हमारे पास app/etc/di.xmlऔर वरीयता हैMagento\Framework\Url\QueryParamsResolver
  • \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig: एक अन्य मामले यहाँ जहां ** एक प्राथमिकता में परिभाषित किया गया है app/etc/di.xmlऔर यह है Magento\Framework\App\Config।
  • $scopeType: यहां हमारे पास केवल एक चर है, जिसके सामने कोई भी वर्ग नहीं है। आपका मॉड्यूल di.xmlनिर्दिष्ट करता है कि Magento\Store\Model\ScopeInterface::SCOPE_STOREइस चर के मान के रूप में उपयोग किया जाना चाहिए। **
  • \Magento\Backend\Helper\Data $backendHelper: यहाँ हम उस वर्ग का उपयोग कर सकते हैं। हालांकि यहां एक प्रॉक्सी क्योंकि इस वर्ग जरूरी इस्तेमाल नहीं किया है किया जा रहा प्रयोग किया जाता है (: प्रॉक्सी कक्षाओं के बारे में जानकारी के लिए इस पोस्ट को देख Magento 2: क्या एक प्रॉक्सी वर्ग है के व्यावहारिक स्पष्टीकरण )
  • \Magento\Backend\Model\Menu\Config $menuConfig : हम इस वर्ग का उपयोग कर सकते हैं।
  • \Magento\Framework\App\CacheInterface $cache: app/etc/di.xmlइस इंटरफ़ेस के लिए एक और प्राथमिकता निर्धारित की गई हैMagento\Framework\App\Cache\Proxy
  • \Magento\Backend\Model\Auth\Session $authSession: यहाँ फिर से हम कक्षा का उपयोग कर सकते हैं लेकिन हम आलसी लोडिंग के लिए प्रॉक्सी क्लास का उपयोग करते हैं।
  • \Magento\Framework\Encryption\EncryptorInterface $encryptor: app/etc/di.xmlफिर से कूदना और हम Magento\Framework\Encryption\Encryptorएक प्राथमिकता के रूप में पाते हैं
  • \Magento\Store\Model\StoreFactory $storeFactory : एक कारखाने तो हम इसे के रूप में उपयोग कर सकते हैं।
  • \Magento\Framework\Data\Form\FormKey $formKey: यहां हम Magento\Framework\Data\Form\FormKey\Proxyआलसी लोडिंग के लिए फिर से एक प्रॉक्सी क्लास का उपयोग करते हैं ।
  • array $data = []: यह एक हमेशा अंतिम आता है और स्वचालित रूप से एक खाली सरणी पर डिफ़ॉल्ट रूप से आ जाता है जिसे आप यहां और अधिक जानकारी प्राप्त कर सकते हैं: Magento 2: $ डेटा सरणी निर्माता पैरामीटर क्या है?

संक्षेप में

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


क्या इंटरफ़ेस पैरामीटर के लिए प्राथमिकता हमेशा आवश्यक है? क्या इसे कमबैक के रूप में देखा जा सकता है? क्या यह समझ में आता है कि विन्यास में एक ठोस तर्क को परिभाषित करने के लिए कहीं भी प्राथमिकता के बिना है? या यह संभव नहीं है?
— रोजबेक

6

निर्भरता की परिभाषा और निर्भरता के विन्यास के बीच अंतर को समझना महत्वपूर्ण है ।

निर्भरताएँ di.xml के अंदर परिभाषित नहीं की जाती हैं। निर्भरता कर रहे हैं निर्माता के अंदर परिभाषित एक अंतरफलक, एक अमूर्त या रूप में एक कारखाने को निर्दिष्ट करके संबंधित वर्ग के प्रकार है कि विशिष्ट निर्भरता, जैसे की $routeConfigप्रकार का एक निर्भरता है \Magento\Framework\App\Route\ConfigInterface।

दूसरी ओर, नोड्स और / या नोड्स का उपयोग करके di.xmlनिर्भरता को कॉन्फ़िगर करने का स्थान है (कभी-कभी अधिक उन्नत कॉन्फ़िगरेशन नोड्स जैसे या ) के साथ युग्मित । एक निर्भरता को कॉन्फ़िगर करने का अर्थ है किसी ऑब्जेक्ट के कंस्ट्रक्टर तर्क को कार्यान्वयन / ऑब्जेक्ट / कंक्रीट पर मैप करना ।<preference/>xpath:type/arguments/argument<virtualType/><proxy/>

आप चाहते हैं कि निर्भरताएँ di.xml के माध्यम से कॉन्फ़िगर की जा सकें, ताकि आप उन्हें स्वैप कर सकें और कुछ शर्तों के तहत एक निश्चित इंटरफ़ेस या तर्क के लिए एक अलग कार्यान्वयन का उपयोग कर सकें (उदाहरण के लिए समझने के लिए उदाहरण पढ़ें कि कुछ शर्तों का क्या मतलब है)।

उदाहरण के लिए, अपने विस्तार को विकसित करते समय आप पहली बार एक नया वर्ग बनाएंगे (हम इस नई कक्षा को एक कार्यान्वयन कहते हैं )। आपका नया वर्ग \Magento\Framework\App\Route\ConfigInterfaceइंटरफ़ेस को लागू करता है और इसके शरीर के अंदर एक ठोस कार्यक्षमता होती है जो इंटरफ़ेस अनुबंध का सम्मान करती है। अब कॉन्फ़िगरेशन भाग शुरू करता है : अपने नए परिभाषित कार्यान्वयन का उपयोग करने के लिए मैगेंटो को बताने के लिए आपको इस कार्यान्वयन को ऑब्जेक्ट के लिए एक निर्भरता के रूप में कॉन्फ़िगर करना होगा Magento\Backend\Model\Url। आप यह कॉन्फ़िगरेशनdi.xml फ़ाइलों या अपने मॉड्यूल के अंदर करते हैं । इस मामले में आपको <preference/>इंटरफ़ेस को अपने नए कार्यान्वयन में मैप करने के लिए नोड का उपयोग करने की आवश्यकता है । अन्य बार आप अधिक दानेदार xpath:type/arguments/argument di.xmlनोड का उपयोग करेंगेविशिष्ट कार्यान्वयन के लिए कंक्रीट के केवल विशिष्ट तर्क (उर्फ निर्भरता, उर्फ ​​इंटरफेस) का नक्शा । अब, आपका कार्यान्वयन केवल \Magento\Backend\Model\Url कुछ शर्तों में ऑब्जेक्ट के लिए निर्भरता के रूप में सक्रिय होगा , उदाहरण के लिए, वर्तमान एप्लिकेशन अनुरोध के कोड निष्पादन प्रवाह में ऑब्जेक्ट का प्रकार Magento\Backend\Model\Urlबनाया जा रहा है और इसे निर्माणकर्ता परिभाषित निर्भरता के लिए कार्यान्वयन की आवश्यकता है जिसे कहा जाता $routeConfigहै प्रकार का \Magento\Framework\App\Route\ConfigInterface।

यह कहना बहुत पसंद है:

"हे होम ऑब्जेक्ट मैनजर! जब भी किसी प्रकार की ऑब्जेक्ट इंस्टेंस का Magento\Backend\Model\Urlअनुरोध किया जाता है, तो कृपया पहले उसकी क्लास कंस्ट्रक्टर परिभाषा पर एक नज़र डालें और उसमें परिभाषित निर्भरता का विश्लेषण करें । मैं चाहता हूं कि आप फ़ाइनल के अंदर देखें, di.xmlवर्तमान HTTP मर्ज के कॉन्फ़िगरेशन का अनुरोध करें। प्रत्येक और हर के लिए कॉन्फ़िगर किया गया निर्भरता कि है परिभाषित में Magento \ बैकएंड \ मॉडल \ यूआरएल वर्ग निर्माता । तुम मुझे दे कि निर्भरता कार्यान्वयन के लिए कॉन्फ़िगर। "

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.