DEPENDENCY INJECTION in MAgento 2

Agenda

  1. Motivation
  2. Object Composition
  3. Object Lifestyle
  4. Interception

Motivation:

  • Complexity
  • Software Entropy

Wrong Approach

Service location
new => Mage::getXXX();

Problems with service location

  • Implicit dependencies
  • God classes
  • Code coupling made easy

Complexity Made Easy

Complex things should be hard to do in application while simple things should be easy. 
~Rich Hickey

Solution

Dependency Injection
Object is abstracted from dependencies through constructor signature
  • Explicit dependencies
  • Honest interfaces
  • Controlled code coupling
  • Unit testable code

Pillar 1: Object Composition



class Magento_Acl_Resource
{
    protected $_resourceProvider;
    
    protected $_resourceFactory;
    
    public function __construct(
        Magento_Acl_ResourceProvider $resourceProvider,
        Magento_Acl_ResourceFactory $resourceFactory,
        $prefix = 'prefix'
    ) {
        $this->_resourceProvider = $resourceProvider;
        $this->_resourceFactory = $resourceFactory;
        $this->_prefix = $prefix;
    }
}

Composition ROOT

http://blog.efvincent.com/di-bootstrap/


class Magento_Acl_Resource
{
    protected $_resourceProvider;
    
    protected $_resourceFactory;
        
    public function __construct(
        Magento_Acl_ResourceProvider $resourceProvider,
        Magento_Acl_ResourceFactory $resourceFactory,
        $prefix = 'prefix'
    ) {
        $this->_resourceProvider = $resourceProvider;
        $this->_resourceFactory = $resourceFactory;
        $this->_prefix = $prefix;
    }
}


class Magento_Acl_Resource
{
    protected $_resourceProvider;
    
    protected $_resourceFactory;
    
    public function __construct(
        Magento_Acl_ResourceProviderInterface $resourceProvider,
        Magento_Acl_ResourceFactory $resourceFactory,
        $prefix = "somePrefix"
    ) {
        $this->_resourceProvider = $resourceProvider;
        $this->_resourceFactory = $resourceFactory;
        $this->_prefix = $prefix;
    }
}


<config>
    <type name="Magento_Acl_Resource">
        <param name="resourceProvider">
            <instance type="Magento_Acl_ResourceProvider" />
        </param>
    </type>
</config>

<config>
    <preference for="Magento_Acl_ResourceProviderInterface"
                type="Magento_Acl_ResourceProvider" />
</config>

Virtual Types

Provide ability to configure set of instances for some class.
<config>
    <virtualType name="customAclResource" type="Magento_Acl_Resource">
        <param name="prefix">
            <value>someOtherPrefix</value>
        </param>
    </virtualType>
    <type name="Magento_Acl_Builder">
        <param name="resource">
            <instance type="customAclResource"/>
        </param>
    </type>
</config>

Pillar 2: Object Lifetime

  • Injectables
  • Non-Injectables

Injectables

  • Mostly services or value objects
  • Mostly stateless
  • Mostly singletons
  • Can be shared or non-shared
  • Don't confuse with Singleton Pattern

Non-shared injectable


<config>
    <type name="Magento_Acl_ResourceProvider" shared="false" />
</config>
or

<config>
    <type name="Magento_Acl_Resource">
        <param name="resourceProvider" shared="false" />
    </type>
</config>

Factories

  • Created for non-injectables
  • Are injectables
  • Can be auto-generated

Optional dependencies


class Magento_Acl_Resource
{
    protected $_resourceProvider;
    
    protected $_resourceFactory;
    
    public function __construct(
        Magento_Acl_ResourceProviderInterface $resourceProvider,
        Magento_Acl_ResourceFactory $resourceFactory,
        $prefix = "someId"
    ) {
        $this->_resourceProvider = $resourceProvider;
        $this->_resourceFactory = $resourceFactory;
        $this->_prefix = $someId;
    }
}

Proxies

  • Object-oriented way to do lazy-loading
  • Resposible for lazy-loading only
  • Can be auto-generated

<config>
    <type name="Magento_Acl_Resource">
        <param name="resourceProvider"
               type="Magento_Acl_ResourceProviderProxy" />
    </type>
</config>

Pillar 3: Interception


Interception Description

Ability to observe public calls.

Interception Demo

Interception Limitations

  • Private calls
  • Methods with final classes
  • Performance

The book


Write me

akril@ebay.com
skype: shupupa

Dependeny Injection in Magento 2

By Anton Kril

Dependeny Injection in Magento 2

  • 6,046