6

I have a M1 module that I'm looking at porting to M2, and part of one of helpers contains code that looks like this:

public function getModel($code)
{
     return Mage::getSingleton('vendor/package_model_' . $code);
}

Given that Magento 2 uses dependency injection, I know that I can specify that I'd like an instance of \Vendor\Package\Model\Interface, but how can I specify that I'd like a specific model?

I'd like to follow best practice, so if it's possible to avoid doing this directly through the ObjectMananger then that would be ideal, but if that's the only option then that's OK too.

3 Answers 3

1

Try to get rid of this shortcut method and use dependency injection to get the actual classes you need where you previously used this.

3
  • Hey Fabian - thanks for the answer. In this particular scenario it needs to be dynamic somehow at least, because the model name depends on the first two characters of a voucher code that gets entered by the user - is there a way that can be achieved before call time?
    – scrowler
    Mar 10, 2016 at 23:04
  • 1
    I think I would create an own factory class in this case and not let Magento instantiate these dynamic classes Mar 10, 2016 at 23:09
  • I like this approach!
    – scrowler
    Mar 10, 2016 at 23:09
1

I hope the code below will help you:

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

public function getModel($code)
{
    $modelins = '\Vendor\Package\Model\\' . $code;
    return $this->objectManager->get($modelins);
}
8
  • Hi Pradeep. I know how to use the object manager to achieve this - but I have read that using it is not good practice, and since I am new to Magento 2 I was wondering if there is a better way to achieve this.
    – scrowler
    Dec 16, 2015 at 3:57
  • On a side note, what is $layersPool for? Also vendor/package_model_xxx won't work, would need to be $modelins = 'Vendor\Package\Model\\' . $code; yeah?
    – scrowler
    Dec 16, 2015 at 4:02
  • 1
    @Robbie :- using \Magento\Core\Model\ObjectManager::getInstance() is bad way , init the object manager and get ur model is fine magento.stackexchange.com/questions/10517/… Dec 16, 2015 at 4:32
  • Great- thanks very much for the explanation. Obviously using DI is preferable where possible though?
    – scrowler
    Dec 16, 2015 at 4:38
  • Could you add a bit of an explanation in your answer for this?
    – scrowler
    Dec 16, 2015 at 4:39
0

Finally I got the answer for how to call class from in DI.

It can be done by using factory in DI and in reader use create() it will be something like this:

<type name="Magento\Catalog\Model\Layer\Resolver">
    <arguments>
        <argument name="layersPool" xsi:type="array">
            <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\CategoryFactory</item>
            <item name="search" xsi:type="string">Magento\Catalog\Model\Layer\SearchFactory</item>
        </argument>
    </arguments>
</type>

In reader file use:

public function create($layerType)
{
    return $this->layersPool[$layerType]->create();
}

So without ObjectManager we can call dynamic class from DI.

3
  • They aren't dynamic though, because you're defining them in XML :-)
    – scrowler
    Oct 30, 2017 at 3:54
  • this work as per the question was posted you have n of class need to call based on param you passed i'e Mage::getSingleton('vendor/package_model_' . $code); Oct 30, 2017 at 5:03
  • But in the background the Magento\Catalog\Model\Layer\Resolver also using objectmanager Jan 19, 2023 at 19:06

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.