ทำไมบางคลาสถึงกำหนด injections ในทั้งนวกรรมิกและ di.xml


12

ฉันไม่เข้าใจว่าทำไมในบางคลาสการประกาศการพึ่งพาของพวกเขาจึงถูกประกาศสองครั้ง - หนึ่งครั้งในdi.xmlและในคอนสตรัคเตอร์ของคลาสคอนกรีต

ตัวอย่างเช่นในMagento\Backend\Model\Url, มันdi.xmlมีชุดประเภทนี้สำหรับการกำหนด DI:

<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 ที่จำเป็นสำหรับการฉีดจะถูกประกาศอีกครั้งใน Constructor:

<?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ในโหนดอาร์กิวเมนต์ของคุณ ตัวจัดการวัตถุจะแทรกอาร์กิวเมนต์เหล่านี้ลงในคลาสในระหว่างการสร้าง ชื่อของอาร์กิวเมนต์ที่กำหนดค่าในไฟล์ 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\Urlวีโอไอพี 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.xmlMagento\Framework\App\Config
  • $scopeType: ที่นี่เรามีตัวแปรเท่านั้นโดยไม่มีคลาสใด ๆ อยู่ข้างหน้า โมดูลของคุณdi.xmlระบุว่าMagento\Store\Model\ScopeInterface::SCOPE_STOREควรใช้เป็นค่าของตัวแปรนี้ **
  • \Magento\Backend\Helper\Data $backendHelper: ที่นี่เราสามารถใช้คลาสนั้นได้ อย่างไรก็ตามที่นี่มีการใช้พร็อกซีเนื่องจากไม่จำเป็นต้องใช้คลาสนี้ (ดูโพสต์นี้สำหรับรายละเอียดเกี่ยวกับคลาสพร็อกซี: วีโอไอพี 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 = []: อันนี้มาล่าสุดเสมอและจะถูกตั้งค่าเริ่มต้นเป็นอาเรย์ที่ว่างโดยอัตโนมัติคุณสามารถหาข้อมูลเพิ่มเติมได้ที่นี่: วีโอไอพี 2: พารามิเตอร์ตัวสร้างอาร์เรย์ข้อมูล $ data คืออะไร

เพื่อสรุป

พารามิเตอร์คอนสตรัคเตอร์ของคลาสเป็นอินเตอร์เฟสหรือคลาสที่ไม่สามารถใช้งานได้ทันที ดังนั้นdi.xmlให้คุณปรับแต่งการพึ่งพาที่คุณต้องการใช้สำหรับตัวสร้างคลาสแต่ละตัว นอกจากนี้ยังใช้ได้กับคลาสที่ใช้งานได้ทันที ตัวอย่างเช่นตัวสร้างคลาสที่ใช้คลาสผลิตภัณฑ์เป็นอาร์กิวเมนต์ตัวสร้าง สามารถปรับแต่งในโมดูลผลิตภัณฑ์ที่กำหนดค่าได้ดังนั้นจึงใช้คลาสผลิตภัณฑ์ที่กำหนดค่าได้แทนอาร์กิวเมนต์


จำเป็นต้องมีการกำหนดค่าตามความชอบสำหรับพารามิเตอร์อินเตอร์เฟสหรือไม่? มันถูกมองว่าเป็นทางเลือกหรือไม่? มันสมเหตุสมผลไหมที่จะกำหนดอาร์กิวเมนต์ที่เป็นรูปธรรมในการกำหนดค่าโดยไม่ต้องมีการตั้งค่าที่ใดก็ได้? หรือว่าเป็นไปไม่ได้?
robsch

6

สิ่งสำคัญคือต้องเข้าใจความแตกต่างระหว่างคำจำกัดความของการอ้างอิงและการกำหนดค่าของการอ้างอิง

การอ้างอิงไม่ได้ถูกกำหนดภายใน di.xml อ้างอิงจะกำหนดภายในนวกรรมิกของชั้นนั้นโดยระบุอินเตอร์เฟซที่เป็นนามธรรมหรือโรงงานเป็นที่ประเภทเฉพาะ dependecy นั้นเช่นเป็นพึ่งพาประเภท$routeConfig\Magento\Framework\App\Route\ConfigInterface

ในทางตรงกันข้ามdi.xmlเป็นสถานที่ในการกำหนดค่าการพึ่งพาโดยใช้<preference/>โหนดและ / หรือxpath:type/arguments/argumentโหนด (บางครั้งคู่กับโหนดการกำหนดค่าขั้นสูงเช่น<virtualType/>หรือ<proxy/>) การกำหนดค่าการพึ่งพาก็หมายความว่าการทำแผนที่อาร์กิวเมนต์ตัวสร้างวัตถุเพื่อการดำเนินการ / วัตถุ / คอนกรีต

คุณต้องการให้สามารถกำหนดค่าการพึ่งพาผ่าน di.xmlเพื่อให้คุณสามารถสลับได้และใช้การใช้งานที่แตกต่างกันสำหรับส่วนต่อประสานหรืออาร์กิวเมนต์ที่แน่นอนภายใต้เงื่อนไขบางอย่าง (อ่านตัวอย่างต่อไปเพื่อทำความเข้าใจว่า

ตัวอย่างเช่นเมื่อพัฒนาส่วนขยายของคุณคุณจะต้องสร้างคลาสใหม่ก่อน (เราเรียกการปรับใช้คลาสใหม่นี้) คลาสใหม่ของคุณใช้\Magento\Framework\App\Route\ConfigInterfaceอินเทอร์เฟซและมันมีฟังก์ชั่นการทำงานที่เป็นรูปธรรมซึ่งให้เกียรติสัญญาอินเทอร์เฟซภายในร่างกาย ตอนนี้เริ่มมีส่วนร่วมกำหนดค่า : ในการสั่งซื้อที่จะบอกวีโอไอพีที่จะใช้ดำเนินการของคุณกำหนดขึ้นใหม่คุณต้องกำหนดค่าการใช้งานนี้เป็น dependecy Magento\Backend\Model\Urlสำหรับวัตถุ คุณทำการกำหนดค่านี้ภายในdi.xmlไฟล์หรือโมดูลของคุณ ในกรณีนี้คุณต้องใช้<preference/>โหนดเพื่อแมปอินเทอร์เฟซกับการใช้งานใหม่ของคุณ ในบางครั้งคุณควรใช้xpath:type/arguments/argument di.xmlโหนดที่ละเอียดยิ่งขึ้นแผนที่การขัดแย้งเท่านั้นที่เฉพาะเจาะจง (aka อ้างอิงอาคาอินเตอร์เฟซ) ของคอนกรีตเพื่อการใช้งานที่เฉพาะเจาะจง ตอนนี้การดำเนินงานของคุณเท่านั้นที่จะใช้งานเป็นพึ่งพาสำหรับวัตถุ\Magento\Backend\Model\Url ในเงื่อนไขบางอย่างเช่นในการไหลโค้ดของการร้องขอโปรแกรมปัจจุบันวัตถุของการพิมพ์ที่Magento\Backend\Model\Urlจะถูกสร้างขึ้นและจะต้องมีการดำเนินการสำหรับการกำหนดตัวสร้างการพึ่งพาที่เรียกว่า$routeConfigซึ่งเป็น \Magento\Framework\App\Route\ConfigInterfaceประเภท

มันค่อนข้างจะเหมือนกับว่า:

"เฮ้นาย ObjectManager! เมื่อใดก็ตามที่เป็นตัวอย่างวัตถุชนิดMagento\Backend\Model\Urlมีการร้องขอโปรดดูได้ที่ระดับความละเอียดคอนสตรัคแรกและวิเคราะห์dependecies ที่กำหนดไว้ในนั้น. ฉันต้องการให้คุณแล้วที่จะค้นหาภายในสุดท้ายรวมdi.xmlของการร้องขอ HTTP ปัจจุบันการกำหนดค่าสำหรับแต่ละและพึ่งพาการกำหนดค่าที่กำหนดไว้ในสร้างคลาสวีโอไอพี \ Backend \ รุ่น \ Url . คุณให้ฉันว่าการกำหนดค่าการดำเนินการพึ่งพา."

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.