4

Magento 2.0 has several optional extensions (they are not necessarily to be installed). How can I safely announce the class dependency for these extensions in my __constract method? Please note that my class is supposed to work even if such extensions don't exist. Simple Example:

  public function __construct(\Magento\Super\Model\System $system)
        {
            $this->_syperSystem = $system;        
        }
        
    //Result:: Class Magento\Super\Model\System does not exist

May be create a factory, which returns a needed object if extension is included or null else and add this factory in __construct() ?

1 Answer 1

4

Note: If you specify the specific module in question, I can update my answer to be more specific.

Depending on the need, you can leverage service contracts for this functionality.

When you use dependency injection in the Magento 2 system, you can specify service contracts, (lower level interfaces) that serve as the basis for your class implementation.

You need to specify the low level service contract (interface) that implements the optional functionality. Once you have specified that interface, you (or Magento) can then specify the preference for that model through the di.xml.

As an example, if you were trying to instantiate your class and pass the product object to your constructor, (which you shouldn't, but that's another article), you specify its low level interface.

Like this:

<?php

namespace Coolryan\Di\Model;

class Example extends \Magento\Framework\Model\AbstractModel {

    protected $product;

    public function __construct(
        Magento\Catalog\Api\Data\ProductInterface $product
    ) {
        $this->product = $product;
    }
}

From there, you can specify the preference for your class being instantiated through your di.xml, like so:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Api\Data\ProductInterface" type="Magento\Catalog\Model\Product" />
</config>

Now the $product instance passed to the constructor will be the class Magento\Catalog\Model\Product. The object manager knows to pass this class because of the preference you specified in your xml.

I hope this helps.

1
  • Thanks for the answer, Ryan. Sorry for the delay). For example, I need use (if exists) class Magento\LayeredNavigation\Model\Attribute\Source\FilterableOptions. So, I can't add it for own __construct() method directly, but I will not add interface instead, because I don't know in advance will be installe the layered navigation extension or not for adding it to di.xml
    – sergei.sss
    Commented Mar 26, 2017 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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