2

I need to create different models by condition.

if($fullActionName == 'catalog_product_view'){
    //get first custom model, 
} elseif($fullActionName == 'catalog_category_view'){
    //get second custom model
}

I find the correct way to do this:

1)

function __construct(FisrtModel $first, SecondModel $second){ ... }

But it's not sense add both model if only one will be use...

2) Get personal model directly use object manager:

$this->_objectManager->create($modelName, $data);

But it's a bad practise..?

2 Answers 2

2
<?php 
class MyFactory // feel free to rename it
{
    public function __construct(
         \Magento\Framework\ObjectManagerInterface $objectManager,
         array $map = []
    ) {
         $this->objectManager = $objectManager;
         $this->map = $map;
    };
    public function create($param) 
    {
         if (!isset($this->map[$param])) {
             throw new \Exception("There is no map value for {$param}"); //or you may just return null here
         }
         return $this->objectManager->create($this->map[$param]);
    }
}

then you need to add this in the di.xml of your module

<type name="MyFactory"> <!-- use here the class name as above -->
    <arguments>
        <argument name="map" xsi:type="array">
            <item name="catalog_product_view" xsi:type="string">First\Model\Name\Here</item>
            <item name="catalog_category_view" xsi:type="string">Second\Model\Name\Here</item>
        </argument>
    </arguments>
</type>

Now you have to inject the class MyFactory in your class and just call

$this->factory->create($fullActionName);

if you choose to throw an exception in the factory, just wrap the code above in a try-catch block, if you choose to return null, just check if it returns null.

This way you make your factory extensible. You can later add a new full action name just by editing the di.xml. You can even hook into this from an other module using the di.xml by adding this:

<type name="MyFactory"> <!-- use here the class name as above -->
    <arguments>
        <argument name="map" xsi:type="array">
            <item name="checkout_cart_index" xsi:type="string">Third\Model\Name\Here</item>
        </argument>
    </arguments>
</type>
0
0

Good way is create CustomModelFactory with method create($fullActionName) and use objectManger to create right instance in it. Also will be good to check that created instance implements some interface and use it in annotation for method, for example: https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Model/Product/CatalogPriceFactory.php

1
  • Thank for your help!
    – sergei.sss
    Jul 30, 2015 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.