Magento2 Best Practices – Using ObjectManager Directly

best practicemagento2moduleobject-manager

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:

  • in static magic methods like __wakeup, serialize, etc
  • in case you should make backward compatibility of constructor
  • in global scope, like in fixtures of integration test.
  • in class that needs only for creation of object like factory, proxy , etc