Menu Close
    Searching for an experienced Magento 2 Development Company ?

    Magento2 Code Generation And Factory Design Pattern

    Magento2 comes with some brilliant features, it makes the developer more perfect in all the perspective such as the most basic writing clean and scalable code and making you aware on new technologies and concepts. Today we will try to understand one of the magento2 feature code generation.

    Code generation as its name explains generates code automatically, code means classes . If you are a magento2 developer and you know about code generation you will be thinking why magento2 needs to generate classes automatically, there are some reasons that could be easily understood :

    • To make some of the classes structure common in all the modules, means if the developer knows about one class he can use that knowledge to any module, since the structure of the class in all the modules is same and you don’t have to write test cases for those classes too.
    • To support the features of plugins in magento2, plugin is a all new feature in magento2, it usese interceptor design pattern , if you don’t know about plugins in magento2 go through this blog :http://webkul.com/blog/magento2-use-plugins/ .
    • Magento2 uses dependency injection design pattern, and since you can pass the object in the constructor of a class like below :
      public function __construct(
      	\MyClassOne $myClassOne,
      	\MyClassTwo $myClassTwo
      )
      {
      	$this->_myClassOne = $myClassOne;
      	$this->_myClassTwo = $myClassTwo;
      }

      when this class is instantiated a chain reaction starts, since the objects passed in the constructor will also get instantiated and the objects defined in there constructor will also get instantiated and so on, so as you can understand now it will result in slow class loading, to overcome this problem magento2 uses proxy design pattern, and the proxy is also generated automatically. We will understand proxy later .

    There are three types of classes that are generated in magento2, these classes are generated in the folder var/generation in magento2 root folder.In this folder it follows the same structure as you module vendor/module.

    • Factory classes
    • Interceptor classes
    • Proxy Classes

    Factory Classes

    Factory is a design pattern that is used to create objects for all the classes instead of using new keyword . It was also used in magento 1 in the form of :

    Mage::getModel(“ClassName”) and Mage::getSingleton(“ClassName”) .

    But here the approach is little different, Magento2 provides an object manager that is responsible for the creation of all the objects.Object Manager resides here
    “Magento\Framework\ObjectManager\ObjectManager”
    it has three methods two of them are responsible for the creation of the objects get() and create(), get is like Mage::getSingleton(“ClassName”) and create is like Mage::getModel(“ClassName”) , get creates sharable object and create will create new objects .
    But using ObjectManager to create all the objects is not a good idea, it prevent the purpose of dependency injection, you should only use constructor to load dependency in the class not the object manager. You can see Magento2 still uses object manager at many places but it will be re-factored in the future for sure.
    Now Back to our main concern code generation, there is always a factory class that is associated with your model class suffixed by ‘Factory’. Suppose you have a model class
    “Webkul\MagentoCodeGeneration\Model\MyModel”

    you want to use its object, there is two ways of creating its object without using object Manager:
    The first method is to pass the class object in the constructor :

    public function __construct(
    	Webkul\MagentoCodeGeneration\Model\MyModel $myModel
    ){
    }

    but this method will always create shared objects, it will not create new object, but what if you want to use new object of this class without using object manager check the second method :

     public function __construct(
    	Webkul\MagentoCodeGeneration\Model\MyModelFactory $myModelFactory
    ){
    	$this->_myModel = $myModelFactory->create();
    }

    The above method will create a new object of the class, you will be thinking what is this ‘MyModelFactory’ do we need to create this class too , the answer is no it will be generated automatically by magento2 code generation script, and it will also have one methods create() and this will also have the same purpose as I have explained in ObjectManager class.

    This factory class is also dependent on the ObjectManager class . When you will load the class or run magento2 compilation using CLI:

    php bin/magento setup:di:compile

    you can found the factory class in:

    var/generation/Webkul/MagentoCodeGeneration/Model/MyModelFactory.php.

    You should always use factories for non-injectable objects, All the entities such as Product, Customer are non-injectable and classes such as EventManager and all the Management classes are injectable in magento2  .Injectable objects don’t have identities but in the case of non-injectable objects they have identities, so you don’t know which instance you need at which time, so you must use Factory classes to inject non-injectable objects.

    Here is the example factory class that is generated for Magento\Customer\Model\Customer, inside var/generation/Magento/Customer/Model/CustomerFactory  :

    <?php
    namespace Magento\Customer\Model;
    
    /**
     * Factory class for @see \Magento\Customer\Model\Customer
     */
    class CustomerFactory
    {
        /**
         * Object Manager instance
         *
         * @var \Magento\Framework\ObjectManagerInterface
         */
        protected $_objectManager = null;
    
        /**
         * Instance name to create
         *
         * @var string
         */
        protected $_instanceName = null;
    
        /**
         * Factory constructor
         *
         * @param \Magento\Framework\ObjectManagerInterface $objectManager
         * @param string $instanceName
         */
        public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Magento\\Customer\\Model\\Customer')
        {
            $this->_objectManager = $objectManager;
            $this->_instanceName = $instanceName;
        }
    
        /**
         * Create class instance with specified parameters
         *
         * @param array $data
         * @return \Magento\Customer\Model\Customer
         */
        public function create(array $data = array())
        {
            return $this->_objectManager->create($this->_instanceName, $data);
        }
    }
    

    Thats it for this time I will explain interceptor design pattern and how it is generated in magento2 in my next article.

    You can also go through this video for better understanding of Magento2 Code Generation.
    If you have any questions in this blog you can ask me questions by commenting below.
    Thanks 🙂 .

    . . .
    Discuss on Helpdesk

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    14 comments

  • Mobeen Sarwar
    Thanks for this article.
    • Archana Tiwari (Moderator)
      Hello Mobeen,
      Thanks for the Appreciation.
  • Kailash Shinde
    Great job! everything is clearly explained.
  • Hitesh Balpande
    It’s ready cool to understand.Thanks for this Article.
  • TS Guhan
    Its really easy to understand for beginners and before starting into magento 2.
  • Vinod Kumar
    Great job! everything is clearly explained.
    • ashutosh srivastava (Moderator)
      Thanks 🙂
  • Magento 2 Learning Resources and Material – Anees Ahmad | Magento Developer Lahore,Pakistan
  • Magento 2 Code Generation and factory design pattern | Web development
    […] On – September 24, 2016 […]
  • Michele Fantetti
    Great article.. compliments!

    But, if I try to call create() method of Factory class in my class constructor in this way (as your example):

    public function __construct(
    MagentoFrameworkViewElementTemplateContext $context,
    MagentoFrameworkRegistry $registry,
    MagentoCatalogModelProductFactory $productFactory,
    MainfExtModelExtFactory $extFactory,
    array $data = []
    ) {
    $this->_coreRegistry = $registry;
    $this->_productFactory = $productFactory;
    $this->_ext = $extFactory->create();
    parent::__construct($context, $data);
    }

    I receive this error message:
    1 exception(s):
    Exception #0 (MagentoFrameworkExceptionLocalizedException): Invalid method MainfExtModelExt::create

    • Ashutosh Srivastava
      thanks for the compliment, you code is correct $this->_ext = $extFactory->create();
      I think you have again called $this->_ext->create() somewhere in your code
      • Michele Fantetti
        I don’t know if I had called $this->_ext->create() more than once in my code (maybe) but now I’ve tried again and it works fine.
        Great!
        Many thanks and compliments again!
        • Ashutosh Srivastava
          thanks 🙂
        • abhishek raj
          I think, You need to run php bin/magento setup:upgrade command whenever you injecting new classes in constructor.
  • Back to Top