2

I hope this is the correct place to ask the question for this. I read the tutorial about DI for Magento 2, I almost get it the concept. How Magento 2 use di in the framework. After reading I get to know that to use di we need to inject our object into the constructor.

But after reading di.xml files of core magento 2 I am little bit confusion, somewhere I see that,

<type name="Magento\Quote\Model\Quote\Address">
        <arguments>
            <argument name="addressConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>
            <argument name="secondConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>
            <argument name="thirdConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>
            ............................
        </arguments>
    </type>

I am not getting why this is written like this? Also, If initialized the Magento\Quote\Model\Quote\Address object then I have access to 3 objects ?so can anyone explain me about this?

EDIT

This is I am using in my custom extension,

  <type name="Vendor\Module\Model\Mymodel">
        <arguments>
            <argument name="dataSource" xsi:type="array">
                <item name="name1" xsi:type="object">Vendor\Module\Model\ModelClass1</item>
                <item name="name2" xsi:type="object">Vendor\Module\Model\ModelClass2</item>
            </argument>
        </arguments>
    </type>

So If Initialize Vendor\Module\Model\Mymodel in my another class constructor like,

protected $myModel;


public function __construct(
    ...
    \Vendor\Module\Model\Mymodel $myModel,  
    ....
) {
    ....
    $this->myModel = $myModel;      
    ....
}

SO If I use $this->myModel in my method then i can have access of ModelClass1 or ModelClass2 ?

1

magento2 DI system works in 2 ways.

First way is to define which object should be used when specific namespace is called in the constructor, ie. if you pass Magento\Catalog\Api\ProductInterface in the constructor DI system will instantiate an object that is set as a preference for this interface. Similarly if you define Magento\Catalog\Model\Product you are able to set preference on that as well and exchange default model for any class you want provided it implements required interface or extends original class. To do that you need to use <preference...> tag in di.xml. This method however is global, which means it will use the preference in each instance in the system.

But if you need something smaller, you need to hook into 1 or few models and make some adjustments there then the above approach will give you 2 main problems: (1) you need to make sure your preference work with all usage of the system (2) it may conflict with another module defining preference for the same interface/class which will end up your implementation not functioning. To avoid that you can tell DI system to use a specific class of your choice for a specific constructor. This way you can still change class being passed to constructor but now it is not global, it works for this specific use case. The part of the code you've seen is for that. It is structured as follows

<type name="Magento\Quote\Model\Quote\Address">

This defines a class you to which constructor want to hook.

<arguments>

This node tells config system you will provide a configuration for the constructor. <type...> node ind di.xml may also be used to define plugins so this node is to make sure what are you doing.

<argument name="addressConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>

Here you define the replacement. name parameter is equal to the variable name in the constructor then xsi:type defines what type of value you will provide, most common used are: object, number, string, array. You can use this way to define not only class variables but any type of variable used in constructor. And finally value of a node defines value to be passed, in this case a class name to be instantiated by DI to inject into constructor.

You do not have to define all arguments used in constructor, you can selectively used the ones you want to change. They do not have to be defined in an order used in constructor.

[EDIT]

When it comes to your edit, whenever Vendor\Module\Model\Mymodel class is instantiated the argument $dataSource in constructor will have at least 2 items with keys name1 and name2 and values of Vendor\Module\Model\ModelClass1 and Vendor\Module\Model\ModelClass2 respectively. When injecting ``Vendor\Module\Model\MyModelto any other class it will be an instance that received those objects. You will be able to access them according to the wayVendor\Module\Model\MyModel` class exposes them.

5
  • Thanks for explanation , suppose If I have class which is already exist in Magento2, then (I mean no proxy class)? So If I initialize Magento\Quote\Model\Quote\Address object then I have access of all objects from arguments ? – Max just now edit – Max Sep 20 '17 at 8:24
  • I am not sure if I understand correctly. di.xml file is to provide configuration what object/value to use for constructor arguments. You can use arguments node to change value of any argument but you cannot add new ones. Magento\Quote\Model\Quote\Address class has 31 arguments so you can provide preference for each one of it. In the case you found core team decided to provide only 1 setting for $addressConfig parameter. – Zefiryn Sep 20 '17 at 10:12
  • Please see my edit @Zefiryn – Max Sep 20 '17 at 11:26
  • @Max I edited my response as well. – Zefiryn Sep 20 '17 at 17:23
  • Thanks ton , It really helps me to understand :) @Zefiryn – Max Sep 21 '17 at 6:55
1

This is an example of proxies. Instead of Magento\Customer\Model\Address\Config, the constructor for Magento\Quote\Model\Quote\Address is passed a proxy object which is a generated type that causes the actual object to be instantiated only if it is actually used. This is to improve performance in cases where a dependency (in this case Magento\Customer\Model\Address\Config) is a resource intensive object that may not get used and therefore shouldn't be instantiated without need.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.