Best DI practices in Magento
  1. Use Constructor Injection: Always inject dependencies through constructors. Magento 2 encourages constructor injection over method injection for better code maintainability and testability.
    public function __construct(
        \Vendor\Module\Model\SomeModel $someModel,
        \Vendor\Module\Helper\Data $helper
    ) {
        $this->someModel = $someModel;
        $this->helper = $helper;
    }
  2. Type Hint Dependencies: Type hint your constructor parameters to specify the class/interface that the dependency should be. This helps with code readability and IDE autocompletion.
  3. Avoid Using Object Manager Directly: Do not use the Object Manager directly to create objects. Instead, rely on constructor injection or factory methods provided by Magento.
    // Avoid
    $object = \Magento\Framework\App\ObjectManager::getInstance()->get('SomeClass');
    // Prefer
    public function __construct(\Vendor\Module\SomeClassFactory $someClassFactory) {
        $this->someClassFactory = $someClassFactory;
    }
  4. Use Factories for Object Creation: When you need to create an instance of a class, use factory classes generated by Magento. Avoid instantiating classes directly.
    public function createSomeObject() {
        $someObject = $this->someClassFactory->create();
        // ...
    }

  5. Keep Constructor Parameter List Short: Avoid having a long list of constructor parameters. If you find that a class requires too many dependencies, it may be a sign that the class has too many responsibilities and should be refactored.
  6. Use Interface Dependencies: When possible, depend on interfaces rather than concrete classes. This makes your code more flexible and allows for easier substitution of implementations.
    public function __construct(\Vendor\Module\Api\SomeInterface $someService) {
        $this->someService = $someService;
    }

  7. Leverage Code Generators: Use code generators like bin/magento dev:di:info and bin/magento dev:di:compile to analyze and optimize your dependency injection configuration.
  8. Avoid Circular Dependencies: Be cautious of circular dependencies, as they can lead to difficult-to-maintain code. Try to design your classes to minimize or eliminate circular dependencies.
  9. Test Your Code: Always write unit tests for your classes to ensure that dependencies are correctly injected and that the class behaves as expected.
  10. Use Service Contracts: Whenever possible, use Magento's service contracts and repositories to interact with database entities. This promotes a consistent and structured way of working with data.
  11. Follow Magento Coding Standards: Adhere to Magento's coding standards and best practices when writing your DI configuration, classes, and methods.
  12. Use Plugins Sparingly: While Magento's plugin system can be powerful, avoid overusing it. Plugins should be reserved for cases where no other solution is feasible.