Ok, so yesterday we had a big talk with other people from the Magento community regarding the direct use of the ObjectManager
in classes/templates.
I'm already aware of the reasons why we shouldn't use the ObjectManager directly, quoting Alan Kent :
There are several reasons. The code will work, but it is best practice
to not reference the ObjectManager class directly.
- Because we say so! 😉 (better expressed as consistent code is good
code)- The code could be used with a different dependency injection
framework in the future- Testing is easier – you pass in mock arguments
for the required class, without having to provide a mock ObjectManager- It keeps dependencies clearer – it is obvious what the code depends on
via constructor list, rather than having dependencies hidden in the
middle of the code- It encourages programmers to think about concepts
like encapsulation and modularization better – if the constructor gets
big, maybe it is a sign the code needs refactoring
From what I've seen in StackExchange, a lot of people tend to go for the easy/short/not recommended solution for example something like this:
<?php
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
Instead of going through the painful but recommended process of:
- creating a module
- declaring preferences
- inject dependencies
- declare a public method
However, and here comes the dilemma, Magento 2 core files often call the ObjectManager directly. A quick example can be found here: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
So here are my questions:
- Why is Magento doing what they recommend us not to do ? Does that mean there are some cases where we should use the
ObjectManager
directly? If so, what are those cases? - What are the consequences of using the ObjectManager directly?
Best Answer
You should not use the ObjectManager directly!
Exception from the rule are:
__wakeup
,serialize
, etc