Dependency injection and Object Manager

Dependency injection sounds like a very complicated term, but when we break it down, it's really quite simple. So let's rewind, and cover the absolute basics of what dependency injection is before we learn how it works in Magento.

A PHP class is a blueprint for creating objects. If you are not familiar with this concept, be sure to check out my PHP 101 course for an introduction to classes and object-oriented programming in PHP.

Use of the new keyword

A class can rely on one or more other classes to perform its functions. The standard way to create implementations of these objects is with the new keyword.

For example, here is a Product class which creates a new category object in the constructor:

<?php

declare(strict_types=1);

namespace Macademy\\Jumpstart\\Model;

class Product
{
    private Category $category;

    function __construct()
    {
        $this->category = new Category();
    }

    function getCategoryName(): string
    {
        return $this->category->getName();
    }
}

When we use the new keyword to create an instance of a class, that instance is created within its own class scope. This practice decentralizes the responsibility of object creation across different classes in our code. This isn’t necessarily an issue, but can lead to tightly-coupled code, making it less flexible and more difficult to isolate for unit testing.

Dependency injection container class

So, what is the alternative? Rather than using the new keyword within constructors, we can have a single class that is responsible for the creation of these objects. This design pattern is known as the “dependency injection container”. In the context of Magento, we call this container class the Object Manager. It’s a very good name, because it’s responsible for the creation and management of all objects in the framework.

This means that every time an object is to be created, the ObjectManager class is the class that is responsible for creating it. By establishing a central class that is responsible for the creation of these objects, this approach significantly enhances the power and flexibility of the framework. Not only is our code now more flexible and easier to test, but it is also much more extensible because objects are now all created in one place. This allows us to change the implementation of any class at any time by swapping in a different implementation. We will explore more about this in a later lesson.

Injecting dependencies

With dependency injection, things become a bit simpler. We remove the new keyword, since the Object Manager is now responsible for the creation of these classes. We’ll move the reference to the class to the constructor, and assign it to a variable name. In this case, it will be $category. We can then assign that value to the class property.

<?php

declare(strict_types=1);

namespace Macademy\\Jumpstart\\Model;

class Product
{
    private Category $category;

    function __construct(Category $category)
    {
        $this->category = $category;
    }

    function getCategoryName(): string
    {
        return $this->category->getName();
    }
}

Now when this Product class gets created and the constructor is executed, arguments defined within that constructor are automatically passed through to the Object Manager. Don’t worry about how this happens — Magento has already implement this for us! Without getting into the lower-level mechanisms, be aware that an instance of the Category class is being created and assigned to the $category variable.

This works exactly the same as before. This is more powerful though, because if the Category class also had any dependencies, which is almost always the case with classes in Magento, those dependencies will also automatically be created by the Object Manager, and so on, all the way down the tree.

Using Object Manager in Magento

The core idea behind the Magento Object Manager is that you don't directly create objects. Instead, you specify your requirements, and the Object Manager provides the instance of the class you need.

In practice, you should never make explicit calls to the Object Manager. Instead, you'll lay out your dependencies within your classes, and the Object Manager will take care of the rest.

To sum up, the Object Manager is a powerful tool in Magento that helps you stick to proper object-oriented programming practices. By discouraging the use of the new keyword, Magento takes a step toward ensuring your code is more testable, modular, and manageable.

That’s all there is to dependency injection! Understanding these basic principles can help demystify complexity about this concept.

Complete and Continue  
Extra lesson content locked
Enroll to access all lessons, source code & comments.
Enroll now to Unlock