Edit in GitHubLog an issue
Thanks to Classy Llama for contributing this topic!

Factories

Factories are service classes that instantiate non-injectable classes, that is, models that represent a database entity. They create a layer of abstraction between the ObjectManager and business code.

Relationship to ObjectManager#

The Magento\Framework\ObjectManager is the class responsible for instantiating objects in the application. Adobe Commerce and Magento Open Source prohibit depending on and directly using the ObjectManager in your code.

Factories are an exception to this rule because they require the ObjectManager to instantiate specific models.

The following example illustrates the relationship between a simple factory and the ObjectManager:

Copied to your clipboard
1<?php
2/**
3 * Copyright © Magento, Inc. All rights reserved.
4 * See COPYING.txt for license details.
5 */
6
7namespace Magento\Framework\App\Config;
8
9use Magento\Framework\ObjectManagerInterface;
10use Magento\Framework\Simplexml\Element;
11use Magento\Framework\App\Config\Base;
12
13class BaseFactory
14{
15 /**
16 * @var ObjectManagerInterface
17 */
18 protected $_objectManager;
19
20 /**
21 * @param ObjectManagerInterface $objectManager
22 */
23 public function __construct(ObjectManagerInterface $objectManager)
24 {
25 $this->_objectManager = $objectManager;
26 }
27
28 /**
29 * Create config model
30 *
31 * @param string|Element $sourceData
32 * @return Base
33 */
34 public function create($sourceData = null): Base
35 {
36 return $this->_objectManager->create(Base::class, ['sourceData' => $sourceData]);
37 }
38}

Writing factories#

Unless you require specific behavior for your factory classes, you do not need to explicitly define them because they are an automatically generated class type. When you reference a factory in a class constructor, Magento's object manager generates the factory class if it does not exist.

Factories follow the naming convention <class-type>Factory where <class-type> is the name of the class the factory instantiates.

For example the automatically generated Magento\Cms\Model\BlockFactory class is a factory that instantiates the class Magento\Cms\Model\Block.

Using factories#

You can get the singleton instance of a factory for a specific model using dependency injection.

The following example shows a class getting the BlockFactory instance through the constructor:

Copied to your clipboard
1function __construct ( \Magento\Cms\Model\BlockFactory $blockFactory) {
2 $this->blockFactory = $blockFactory;
3}

Calling the create() method on a factory gives you an instance of its specific class:

Copied to your clipboard
$block = $this->blockFactory->create();

For classes that require parameters, the automatically generated create() function accepts an array of parameters that it passes on to the ObjectManager to create the target class.

The example below shows the construction of a \Magento\Framework\FlagFactory object by passing in an array of parameters to a factory:

Copied to your clipboard
1$flag = $this->flagFactory->create([
2 'data' => ['flag_code' => 'something']
3]);

The Flag class has a $data constructor parameter which corresponds to the data key in the create array above.

Interfaces#

Factories are smart enough to resolve dependencies and allow you to get the correct instance of an interface as defined in your module's di.xml.

For example, in the CatalogInventory module, the di.xml file contains the following entry:

Copied to your clipboard
<preference for="Magento\CatalogInventory\Api\Data\StockItemInterface" type="Magento\CatalogInventory\Model\Stock\Item" />

It instructs the application to use the specific Item class wherever the StockItemInterface is used. When a class in that module includes the factory StockItemInterfaceFactory as a dependency, the application generates a factory that is capable of creating the specific Item objects.

Was this helpful?
  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.