Upload
sergii-shymko
View
135
Download
2
Embed Size (px)
Citation preview
Code Generationin Magento 2
Sergii ShymkoSenior Software EngineerMagento, an eBay Inc. company
Legal Disclaimer
Copyright © 2015 Magento, Inc. All Rights Reserved.
Magento®, eBay Enterprise™ and their respective logos are trademarks, service marks, registered trademarks, or registered service marks of eBay, Inc. or its subsidiaries. Other trademarks or service marks contained in this presentation are the property of the respective companies with which they are associated.
This presentation is for informational and discussion purposes only and should not be construed as a commitment of Magento, Inc. or eBay Enterprise (“eBay Enterprise”) or of any of their subsidiaries or affiliates. While we attempt to ensure the accuracy, completeness and adequacy of this presentation, neither Magento, Inc., eBay Enterprise nor any of their subsidiaries or affiliates are responsible for any errors or will be liable for the use of, or reliance upon, this presentation or any of the information contained in it. Unauthorized use, disclosure or dissemination of this information is expressly prohibited.
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
Code Generation in Magento 1.x
Code Generation in Magento 2
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/
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
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
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
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
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
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
Interception
• Primary customization approach• AOP-like mechanism• Used for plugins• Attach behavior to public methods
– Before– After– Around
• Plugins declared in DI config
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
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
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
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
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
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
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
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
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
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
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
Summary of Code Generation
• DI– Factory– Proxy
• Interception• Service Layer
– Repository– Persistor– Search Results– Extension Attributes
• Logger
Resources
• github.com– magento/magento2 – Magento 2 Community Edition– magento/magento2-community-edition – Composer project for
Magento 2 CE• devdocs.magento.com
– Factories– Proxies– Plugins– Definition compilation tool