black magic of code generation in magento 2

25
#mm15de @SergiiShymko Senior Software Engineer Magento, an eBay Inc. company Code Generation in Magento 2

Upload: sergii-shymko

Post on 16-Apr-2017

268 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Black Magic of Code Generation in Magento 2

#mm15de

@SergiiShymkoSenior Software EngineerMagento, an eBay Inc. company

Code Generationin Magento 2

Page 2: Black Magic of Code Generation in Magento 2

#mm15de

Introduction to Code Generation

• Automatic programming – generation of computer program• Source code generation

– Generation based on template• Allows to write code at higher abstraction level• Enables aspect-oriented programming (AOP)• Enables generic programming – parameterization over types• Avoids writing boilerplate code

Page 3: Black Magic of Code Generation in Magento 2

#mm15de#mm15de

Code Generation in Magento 1.x

Page 4: Black Magic of Code Generation in Magento 2

#mm15de#mm15de

Code Generation in Magento 2

Page 5: Black Magic of Code Generation in Magento 2

#mm15de

Code Generation in Magento 2

• Code is generated:– On the fly (development)

• Autoload non-existing class that follows naming pattern– Beforehand (production)

• Run CLI toolsphp dev/tools/Magento/Tools/Di/compiler.php

• Location of generated code:var/generation/

Page 6: Black Magic of Code Generation in Magento 2

#mm15de

Factories

• Factory creates objects• Single method – create()• Used for non-injectables, i.e. entities• Isolation from Object Manager• Type safety• IDE auto-completion• Class name pattern:

\Namespace\ClassFactory

Page 7: Black Magic of Code Generation in Magento 2

#mm15de

Factory Usage

namespace Magento\Catalog\Model\Product;

class Copier{ public function __construct( \Magento\Catalog\Model\ProductFactory $productFactory ) { $this->productFactory = $productFactory; }

public function copy(\Magento\Catalog\Model\Product $product) { $duplicate = $this->productFactory->create(); // ... }}

app/code/Magento/Catalog/Model/Product/Copier.php

Page 8: Black Magic of Code Generation in Magento 2

#mm15de

Generated Factory (Simplified)

namespace Magento\Catalog\Model;

class ProductFactory{ public function __construct( \Magento\Framework\ObjectManagerInterface $objectManager ) { $this->objectManager = $objectManager; }

public function create(array $data = array()) { return $this->objectManager->create( '\\Magento\\Catalog\\Model\\Product', $data ); }}

var/generation/Magento/Catalog/Model/ProductFactory.php

Page 9: Black Magic of Code Generation in Magento 2

#mm15de

Proxies

• Implementation of GoF pattern• Follows interface of subject• Delays creation of subject

– Delays creation of dependencies• Forwards calls to subject• Used for optional dependencies of DI• Class name pattern:

\Namespace\Class\Proxy

Page 10: Black Magic of Code Generation in Magento 2

#mm15de

Proxy Usage in DI Config

<config> <type name="Magento\Catalog\Model\Resource\Product\Collection"> <arguments> <argument name="customerSession" xsi:type="object"> Magento\Customer\Model\Session\Proxy </argument> </arguments> </type></config>

app/code/Magento/Catalog/etc/di.xml

Page 11: Black Magic of Code Generation in Magento 2

#mm15de

Generated Proxy (Simplified)

namespace Magento\Customer\Model\Session;

class Proxy extends \Magento\Customer\Model\Session{ protected function getSubject() { if (!$this->subject) { $this->subject = $this->objectManager->get( '\\Magento\\Customer\\Model\\Session' ); } return $this->subject; }

public function getCustomerId() { return $this->getSubject()->getCustomerId(); }

// ...}

var/generation/Magento/Customer/Model/Session/Proxy.php

Page 12: Black Magic of Code Generation in Magento 2

#mm15de

Interception

• Primary customization approach• AOP-like mechanism• Used for plugins• Attach behavior to public methods

– Before– After– Around

• Plugins declared in DI config

Page 13: Black Magic of Code Generation in Magento 2

#mm15de

Plugin Implementation

namespace Magento\Store\App\Action\Plugin;

class StoreCheck{ public function aroundDispatch( \Magento\Framework\App\Action\Action $subject, \Closure $proceed, \Magento\Framework\App\RequestInterface $request ) { if (!$this->storeManager->getStore()->getIsActive()) { throw new \Magento\Framework\App\InitException( 'Current store is not active.' ); } return $proceed($request); }}

app/code/Magento/Store/App/Action/Plugin/StoreCheck.php

Page 14: Black Magic of Code Generation in Magento 2

#mm15de

Plugin Declaration in DI Config

<config> <type name="Magento\Framework\App\Action\Action"> <plugin name="storeCheck" type="Magento\Store\App\Action\Plugin\StoreCheck" sortOrder="10"/> </type></config>

app/code/Magento/Store/etc/di.xml

Page 15: Black Magic of Code Generation in Magento 2

#mm15de

Generated Interceptor (Simplified)

namespace Magento\Framework\App\Action\Action;

class Interceptor extends \Magento\Framework\App\Action\Action{ public function dispatch( \Magento\Framework\App\RequestInterface $request ) { $pluginInfo = $this->pluginList->getNext( '\\Magento\\Framework\\App\\Action\\Action', 'dispatch' ); if (!$pluginInfo) { return parent::dispatch($request); } else { return $this->___callPlugins( 'dispatch', func_get_args(), $pluginInfo ); } }}

var/generation/Magento/Framework/App/Action/Action/Interceptor.php

Page 16: Black Magic of Code Generation in Magento 2

#mm15de

Code Generation for Service Layer

• Service layer – ultimate public API• Services implement stateless operations• Generated code:

– Repository*– Persistor*– Search Results– Extension Attributes

* – may be removed in future releases

Page 17: Black Magic of Code Generation in Magento 2

#mm15de

Generated Repository (Simplified)

namespace Magento\Sales\Api\Data\Order;

class Repository implements \Magento\Sales\Api\OrderRepositoryInterface{ public function __construct( \Magento\Sales\Api\Data\OrderInterfacePersistor $orderPersistor, \Magento\Sales\Api\Data\OrderSearchResultInterfaceFactory $searchResultFactory ) { $this->orderPersistor = $orderPersistor; $this->searchResultFactory = $searchResultFactory; }

public function get($id); public function create(\Magento\Sales\Api\Data\OrderInterface $entity); public function getList(\Magento\Framework\Api\SearchCriteria $criteria); public function remove(\Magento\Sales\Api\Data\OrderInterface $entity); public function flush();}

var/generation/Magento/Sales/Api/Data/Order/Repository.php

Page 18: Black Magic of Code Generation in Magento 2

#mm15de

Extension Attributes

• Extension to data interfaces from 3rd party modules• Attributes declared in configuration• Attribute getters/setters generated• Type-safe attribute access• IDE auto-completion• Class name pattern:

\Namespace\ClassExtensionInterface\Namespace\ClassExtension

Page 19: Black Magic of Code Generation in Magento 2

#mm15de

Declaration of Extension Attributes

<config> <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <attribute code="price_type" type="integer" /> </custom_attributes></config>

app/code/Magento/Bundle/etc/data_object.xml

Page 20: Black Magic of Code Generation in Magento 2

#mm15de

Entity with Extension Attributes

namespace Magento\Catalog\Api\Data;

interface ProductInterface extends \Magento\Framework\Api\CustomAttributesDataInterface{ /** * @return \Magento\Catalog\Api\Data\ProductExtensionInterface|null */ public function getExtensionAttributes();

public function setExtensionAttributes( \Magento\Catalog\Api\Data\ProductExtensionInterface $attributes );

// ...}

app/code/Magento/Catalog/Api/Data/ProductInterface.php

Page 21: Black Magic of Code Generation in Magento 2

#mm15de

Generated Interface of Extension Attributes

namespace Magento\Catalog\Api\Data;

interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface{ /** * @return integer */ public function getPriceType();

/** * @param integer $priceType * @return $this */ public function setPriceType($priceType);

// ...}

var/generation/Magento/Catalog/Api/Data/ProductExtensionInterface.php

Page 22: Black Magic of Code Generation in Magento 2

#mm15de

Generated Implementation of Extension Attributes

namespace Magento\Catalog\Api\Data;

class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements \Magento\Catalog\Api\Data\ProductExtensionInterface{ /** * @return integer */ public function getPriceType() { return $this->_get('price_type'); } /** * @param integer $priceType * @return $this */ public function setPriceType($priceType) { return $this->setData('price_type', $priceType); }

// ...}

var/generation/Magento/Catalog/Api/Data/ProductExtension.php

Page 23: Black Magic of Code Generation in Magento 2

#mm15de

Loggers

• Implementation of GoF pattern Decorator• Activated with the profiler

– Object Manager wraps instances with loggers• Tracks method call stack• Forwards calls to original methods• Class name pattern:

\Namespace\Class\Logger

Page 24: Black Magic of Code Generation in Magento 2

#mm15de

Summary of Code Generation

• DI– Factory– Proxy

• Interception• Service Layer

– Repository– Persistor– Search Results– Extension Attributes

• Logger

Page 25: Black Magic of Code Generation in Magento 2

#mm15de

Thank You!Q & A@SergiiShymko

[email protected]@shymko.net