5

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.

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.

  • 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? – Robbie Averill Mar 10 '16 at 23:04
  • I think I would create an own factory class in this case and not let Magento instantiate these dynamic classes – Fabian Schmengler Mar 10 '16 at 23:09
  • I like this approach! – Robbie Averill Mar 10 '16 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);
}
  • 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. – Robbie Averill Dec 16 '15 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? – Robbie Averill Dec 16 '15 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/… – Pradeep Kumar Dec 16 '15 at 4:32
  • Great- thanks very much for the explanation. Obviously using DI is preferable where possible though? – Robbie Averill Dec 16 '15 at 4:38
  • Could you add a bit of an explanation in your answer for this? – Robbie Averill Dec 16 '15 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 some thing 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 with out object manger we can call dynamic class from DI

  • They aren't dynamic though, because you're defining them in XML :-) – Robbie Averill Oct 30 '17 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); – Pradeep Kumar Oct 30 '17 at 5:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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