# Using dependency injection with WordPress

As you use [object-oriented programming with WordPress](https://carlalexander.ca/object-oriented-programming-next-step-wordpress-developer/) more and more, you're going to encounter new sets of problems. These problems aren't as simple as the ones that you encountered when you [started](https://carlalexander.ca/first-thing-learn-object-oriented-programming/). But that's also good news. It also means that you're making progress. One set of problems that you start to encounter as you advance in your use of object-oriented programming deal with scaling. As your code has more and more classes, it becomes a challenge to assemble these classes together. That's why in the past [we looked at how to design a class](https://carlalexander.ca/designing-class-assemble-plugin) whose job was to do that. But there are other problems that come with having a lot of classes in your code. It's how much your classes depend on other classes. This is what we call [coupling](https://carlalexander.ca/coupling-cohesion-wordpress/) in programming. (Not just object-oriented programming.) To help with coupling, a famous software engineer ([Robert C. Martin](https://en.wikipedia.org/wiki/Robert_C._Martin) who's also known as Uncle Bob) created the [dependency inversion principle](https://carlalexander.ca/dependency-inversion-principle-wordpress/). It helps you decouple your classes by making dependencies external to them. (There's more to it than that. But this is one of the core elements of the dependency inversion principle.) This reduces coupling but creates a new problem as well. That problem is that you can't initialize objects inside your class anymore. You have to pass them to your own object through its constructor or some other method like a [setter method](https://en.wikipedia.org/wiki/Mutator_method). This makes it even harder to assemble your classes together. This is why software engineers created [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection). It's a programming technique that helps solve this problem. Most [web application frameworks](https://en.wikipedia.org/wiki/Web_framework) use it in some form or another. But that's not the case with WordPress since a lot of its code isn't object-oriented. That said, if you want to build an object-oriented plugin for WordPress, it's pretty much mandatory. Lucky for us, it's not that hard to use dependency injection in your own code!

# A small warning about PHP versions

While it's not recommended anymore, WordPress still has a [minimum requirement](https://wordpress.org/about/requirements/) of PHP 5.2.4. And, while it's not impossible to use dependency injection with PHP 5.2, it's a lot harder. For the sake of keeping our implementation of dependency injection simple, we're going to use a specific feature from PHP 5.3. That feature is [anonymous functions](https://secure.php.net/manual/en/functions.anonymous.php). Anonymous functions as their name implies are functions without a name. (And thus anonymous!) We'll look at why we want to use anonymous functions to implement dependency injection a bit later. This was just a small warning before we get further into this article. If your code has to support PHP 5.2, you won't be able to use the code that you'll see in this article. That said, dependency injection is still a super important concept in modern programming. (So you'll still learn something useful!) # Going over some concepts

Before we can begin, let's go over some important concepts. They'll help you make sense of what we're doing throughout the rest of the article. ## Dependency injection explained

First, there's dependency injection. (The topic of this article!) We mentioned earlier that it's a programming technique. But that's a pretty vague description. It doesn't tell us that much about it. The story behind dependency injection begins with the dependency inversion principle. Without it, there would be no need for dependency injection. That's because, as we explained in the introduction, the dependency inversion principle forces you to move your class's dependencies outside of it. You want to do that because it reduces the amount of coupling that your class has. And one way that the dependency inversion principle achieves that is by removing the [instantiation of new objects](https://secure.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new) from your class. Instead of doing that, you need to pass those objects to your class using a constructor or a method. But your class still needs to receive its objects from somewhere. If you can't do it inside your class, where can you do it? Well, as you can guess, that's the question that dependency injection wants to answer! Dependency injection is this idea that there should be a system that handles these objects that your class depends on. This system would inject those objects (thus the name dependency injection!) into your class. It can do either by constructing the object and passing it its dependencies. Or it can use methods that you've created for that purpose like setter methods. We call those [constructor injection](https://en.wikipedia.org/wiki/Dependency_injection#Constructor_injection) and [setter injection](https://en.wikipedia.org/wiki/Dependency_injection#Setter_injection) respectively. ## On service classes and singletons

But dependency injection isn't the only concept that we need to go over. There's another important one that you need to understand with dependency injection. It's the idea of a [service](https://en.wikipedia.org/wiki/Service_(systems_architecture)). A service is a class that offers a specific functionality (or service!) that your application depends on. At a glance, there's no obvious difference between a class that's a service and one that's not. That's due to the fact that what makes a service special and worth discussing is how you instantiate it. A service is often a class that you want to instantiate only once. But why would you want to instantiate a service class only once? It's because that service object represents the service for the entire application. If a class needs to use that service, it really just wants to use that one service object. This is why it's common for people new to object-oriented programming to build their service classes using the [singleton pattern](https://carlalexander.ca/singletons-in-wordpress/). This helps them enforce this single object requirement for service objects. This is also why a lot of WordPress developers end up designing all their classes as singletons. Most of the classes that they create are service classes. And they feel compelled to use the singleton pattern to ensure they get created once. This is why we're seeing the concept of a service class. Being able to create service objects is an important part of any dependency injection system. This means that, by implementing your own dependency injection system, you should be able to move beyond the use of singletons. (Yay!) # Using dependency injection

Now that we've gone over the concepts surrounding dependency injection, we can start looking at how to use it. As we mentioned earlier, dependency injection relies on a system to inject our objects. This system can be large and complex with a lot of classes. But it can also be small with a single class doing all the work. As you can guess, we're not interested in building a large dependency injection system. We're going to keep this simple and build one class to handle dependency injection for us. We call this class a container. ## Building a container class

Alright, so let's begin building our `MyPlugin_Container` class! As usual, we're going to start with an empty class. You can find it below: ```
class MyPlugin_Container
{
}
```

### Adding some storage

But a container wouldn't be a container without some way of storing things inside of it. The easiest way to do that is with an array. So let's add that to our `MyPlugin_Container` class. ```
class MyPlugin_Container
{
    /**
     * Values stored inside the container.
     *
     * @var array
     */
    private $values;

    /**
     * Constructor.
     *
     * @param array $values
     */
    public function __construct(array $values = array())
    {
        $this->values = $values;
    }

    // ...
}
```

Above you can see that we added the `values` properties to our `MyPlugin_Container` class. This is the class property that we'll use to store everything in our container. We also need it to be an array. That's why we also added a [constructor](https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)) to our `MyPlugin_Container` class. The constructor has `values` as a parameter which we force to be an array using [type hinting](https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration). We also give it an empty as a default value. This ensures that, when we assign it to the `values` property, it's always an array. ### Accessing our storage

Now, the `values` property that added is private. That means that there's no way for other developers to access the values stored in the container. As with most things in programming, there are various ways that we can do this. (Wouldn't it just be more convenient if there was always one good answer!?) Most of us are familiar with [arrays](https://en.wikipedia.org/wiki/Array_data_type), so it would make a lot of sense if our `MyPlugin_Container` class behaved like one. This is something that isn't too complicated to do. We just need our class to implement a specific PHP [interface](https://carlalexander.ca/polymorphism-wordpress-interfaces/). ```
class MyPlugin_Container implements ArrayAccess
{
}
```

The interface in question is the `ArrayAccess` interface. It's an interface that lets you access objects like you would an array. The interface requires that we implement four methods: `offsetExists`, `offsetGet`, `offsetSet` and `offsetUnset`. #### Implementing the interface

Let's look at how we'll implement these methods in our `MyPlugin_Container` class. That said, we won't implement them all right away. We'll start with three of the four methods that the `ArrayAccess` interface wants. ```
class MyPlugin_Container implements ArrayAccess
{
    // ...

    /**
     * Checks if there's a value in the container for the given key.
     *
     * @param mixed $key
     *
     * @return bool
     */
    public function offsetExists($key)
    {
        return array_key_exists($key, $this->values);
    }

    /**
     * Sets a value inside of the container.
     *
     * @param mixed $key
     * @param mixed $value
     */
    public function offsetSet($key, $value)
    {
        $this->values[$key] = $value;
    }

    /**
     * Unset the value in the container for the given key.
     *
     * @param mixed $key
     */
    public function offsetUnset($key)
    {
        unset($this->values[$key]);
    }

    // ...
}
```

You can see the three methods that we implemented in our `MyPlugin_Container` class above. The `offsetGet` method is the method that we left out. It's a much more important component of our dependency injection container so we're going to cover it a bit later. The first method that we added was the `offsetExists` method. PHP will call it when you do an [`isset`](https://secure.php.net/manual/en/function.isset.php) check on your object like you would on an array. The method itself returns the result of the call to the [`array_key_exists`](https://secure.php.net/manual/en/function.array-key-exists.php) function. We pass it the `key` value that you used with the object and our `values` array. The second method is `offsetSet`. This is the method that PHP will call when you try to assign a value to your object like you would with an array. The method has two parameters: `key` and `value`. We just use the `key` value as the index for our `values` array and `value` is the value that we assign to it. The `offsetUnset` method has the opposite effect of the `offsetSet` method. PHP will call this method when you want to remove a value from your object. This happens when you use the [`unset`](https://secure.php.net/manual/en/function.unset.php) function on your object like you would on an array. We just do the same call to the `unset` function on our `values` array. ### Going back to anonymous functions and services

So why haven't didn't we implement the `offsetGet` method with the others? Well, that's because it's where the magic inside of our `MyPlugin_Container` class happens! But before we can look behind the scenes at how that magic works, we need to take a step back. That's because we need to talk more about two concepts that we talked about earlier. These two concepts are anonymous functions and services. It's time to look how they fit into the larger picture of dependency injection. #### The link between anonymous functions and dependency injection

Let's start with anonymous functions. Why are anonymous functions so critical to dependency injection? It's because they allow us to encapsulate the creation of an object. ```
$myplugin_class = function () {
    return new MyPlugin_Class();
};
```

Here's an example of an anonymous function. The function returns a new instance of the `MyPlugin_Class` class. (To keep things simple for now, we'll say that the `MyPlugin_Class` class constructor doesn't take any arguments.) ```
$myplugin_object1 = $myplugin_class();
$myplugin_object2 = $myplugin_class();
```

We can then use the variable containing our anonymous function to create new objects. Both `myplugin_object1` and `myplugin_object2` are different instances of MyPlugin\_Class. So, if you did `$myplugin_object1 === $myplugin_object2`, it would return `false`. We call the `===` [comparision operator](https://secure.php.net/manual/en/language.operators.comparison.php) an identical check. With objects, it will only return `true` if the objects share the [same reference](https://secure.php.net/manual/en/language.oop5.references.php). Since we created two different objects with our anonymous function, they aren't identical. That's why `$myplugin_object1 === $myplugin_object2` returns `false`. #### Using anonymous functions for services

But, if we want to use an anonymous function to create a service object, we need our two objects to be identical. This means that we need our anonymous function to return the same service object every time. So let's create an anonymous function that creates a service object instead of a new one each time. ```
$myplugin_class_service = function ()  {
    static $object;

    if (!$object instanceof MyPlugin_Class) {
        $object = new MyPlugin_Class();
    }

    return $object;
};
```

The key to creating a service object with an anonymous function is to use the [`static`](https://secure.php.net/manual/en/language.variables.scope.php#language.variables.scope.static) keyword. If you've designed a singleton before, there's a good chance that the structure of the anonymous function is familiar to you. It's pretty much the same as the one you'd see in a singleton. We start by defining an `object` variable using the `static` keyword. We then use a [guard clause](https://carlalexander.ca/mastering-php-conditionals/) to check if we've assigned a value to our `object` variable. We do this by using the [`instanceof`](https://secure.php.net/manual/en/language.operators.type.php) to check if `object` is an instance of `MyPlugin_Class`. ```
$myplugin_object1 = $myplugin_class_service();
$myplugin_object2 = $myplugin_class_service();
```

Now, let's go back to code that we used earlier to create to create `myplugin_object1` and `myplugin_object2`. We changed it to use our new `myplugin_class_service` anonymous function to create the objects. In this scenario, both `myplugin_object1` and `myplugin_object2` will be identical. If you did `$myplugin_object1 === $myplugin_object2`, it would return `true`. ### Getting objects from our container

Alright, so now we can go back to our missing `offsetGet` method! The goal of our `MyPlugin_Container` class is to be able to store anonymous functions like the ones that we just saw. So the code that we had earlier would become something like this: ```
$container['myplugin_class'] = function () {
    return new MyPlugin_Class();
};

$myplugin_object = $container['myplugin_class'];
```

The issue with this example is that our dependency injection container can also store other things. It doesn't just store anonymous functions. So we need a way for it to know if we're trying to create an object with an anonymous function. ```
$container['myplugin_class'] = function () {
    return new MyPlugin_Class();
};
$container['myplugin_variable'] = 'variable';

$myplugin_object = $container['myplugin_class'];
$myplugin_variable = $container['myplugin_variable'];
```

Our `offsetGet` method needs to work for both `myplugin_object` and `myplugin_variable`. For `myplugin_object`, would return a new instance of the `MyPlugin_Class` class. And, for `myplugin_variable`, it needs to just return the value that we stored. #### Anonymous functions are objects

To do that, we're going to use a lesser known fact about anonymous functions. In PHP, anonymous functions are actually instances of the [`Closure`](https://secure.php.net/manual/en/class.closure.php) class. This means that we can detect if we stored anonymous function by using the `instanceof` operator. ```
class MyPlugin_Container implements ArrayAccess
{
    // ...

    public function offsetGet($key)
    {
        if (!array_key_exists($key, $this->values)) {
            return new WP_Error('no_value_found', sprintf('Container doesn\'t have a value stored for the "%s" key.', $key));
        }

        return $this->values[$key] instanceof Closure ? $this->values[$key]() : $this->values[$key];
    }

    // ...
}
```

So here's our `offsetGet` method at last! For all the explanations that we went through, it's still a small method. That said, there are still a few more things going on that are worth explaining. First, we have a guard clause. It checks if we even have the given `key` in our `values` array. We perform the check using the `array_key_exists` function like we did in the `offsetExists` method. If the `key` isn't present in our `values` array, we return a `WP_Error` object. (You could also throw a [`InvalidArgumentException`](https://secure.php.net/manual/en/class.invalidargumentexception.php) if you prefer!) Otherwise, we return the value stored in our dependency injection container for the given `key`. We use the [ternary operator](https://secure.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary) to do that. We use it to determine if we stored an anonymous function or not. If we have an instance of a `Closure`, we call our stored value as a function. (Like we did earlier!) Otherwise, we just return it as is. ### Storing a service object

At this point, our `MyPlugin_Container` is pretty well rounded. But there's still one more element that we haven't covered yet. It's how to create service objects using our dependency injection container. We saw earlier that we can create service objects using an anonymous function and the `static` keyword. But, in our example, we also created manually by doing `new MyPlugin_Class()`. This doesn't work with the way that we create objects with our dependency injection container. With our dependency injection container, we use anonymous functions to create our objects. This means that our anonymous function for creating service objects should work with them as well. We can do this by making the anonymous function for creating service objects reusable. ```
class MyPlugin_Container implements ArrayAccess
{
    // ...

   public function service(Closure $closure)
    {
        return function () use ($closure) {
            static $object;

            if (null === $object) {
                $object = $closure();
            }

            return $object;
        };
    }

    // ...
}
```

This is the goal of the `service` method above. The method has a single parameter: `closure`. We also enforce that `closure` is a `Closure` object using a type hint. The method itself just returns an anonymous function similar to the one we saw earlier for service objects. We pass this `closure` to another anonymous function using the `use` language construct. (We're going full closure inception here!) The anonymous function then uses that `closure` if we didn't create that object already. ```
$container['service'] = $container->service(function () {
    return new MyPlugin_Class();
});
```

And here is how we'd use our `service` method with our `container`. We store the anonymous function returned by the `service` method inside our dependency injection container. And we pass the `service` method the anonymous function that creates our `MyPlugin_Class` object. ## Injecting dependencies with our container

Alright, so, at this point, our `MyPlugin_Container` class is pretty much done. That said, to keep things simple, we worked under an important assumption. It's that the constructor of our `MyPlugin_Class` (or any other class) doesn't take any arguments. But that's not how things work in practice. Most classes have constructors that require that you pass them one or more arguments. That's the point of dependency injection after all! So we need to tweak our `MyPlugin_Container` class so that we can inject dependencies when we create our objects. The way we do this is pretty simple. All that we have to do is pass our `MyPlugin_Container` object to our anonymous functions. If we did that, we could create anonymous functions that look like this: ```
$container['myplugin_class'] = function (MyPlugin_Container $container) {
    return new MyPlugin_Class($container['service']);
};
```

You'll notice that we added our `MyPlugin_Container` as a parameter of our anonymous function. This lets us use our dependency injection container inside the anonymous function. And that way we can use it to inject a dependency into our `MyPlugin_Class`. This is the trick to doing dependency injection with this type of dependency injection container. We pass the dependency injection container to the anonymous functions creating our objects. And they use it to inject the dependencies that they need to create the object in question. ### Modifying our container class

Alright! So the only thing left to do is to modify our `MyPlugin_Container` class. We need it to pass itself to our anonymous functions when it calls them. This isn't too hard to do because there are only two places where this happens in our `MyPlugin_Container` class. ```
class MyPlugin_Container implements ArrayAccess
{
    // ...

    public function offsetGet($key)
    {
        if (!array_key_exists($key, $this->values)) {
            return new WP_Error('no_value_found', sprintf('Container doesn\'t have a value stored for the "%s" key.', $key));
        }

        return $this->values[$key] instanceof Closure ? $this->values[$key]($this) : $this->values[$key];
    }

    // ...

    public function service(Closure $closure)
    {
        return function (MyPlugin_Container $container) use ($closure) {
            static $object;

            if (null === $object) {
                $object = $closure($container);
            }

            return $object;
        };
    }
}
```

Above is our modified `MyPlugin_Container` class. We made two small changes to it. Those were at the two locations where we interacted with anonymous functions. The first change is in the `offsetGet` method. We now pass the anonymous function a copy of the object when we have the `values` array stores a `Closure`. We do this by passing the `this` pseudo-variable representing our object to the anonymous function. The other change that we did is to the `service` method. Here, we changed the anonymous function that the method returns. It now has a `container` parameter like the anonymous function that we saw earlier. # Organizing the configuration of our container

So, at this point, our `MyPlugin_Container` class is fully functional. You can use it in your plugin to create that objects that it needs. That said, there's still a small improvement that we can make to it. This improvement relates to how we configure our dependency injection container. So far, our dependency injection container configuration examples have been quite simple. We were always configuring a single service or object. But this isn't how things will play out in practice. In reality, you'll have dozens of classes, parameters and services. And you'll want to configure them all inside your dependency injection container. This can get messy really fast if you don't have a way to organize things. (You always want to [keep your files organized](https://carlalexander.ca/organizing-files-object-oriented-wordpress-plugin/)!) This is the final improvement that we'll make to our `MyPlugin_Container` class. We'll create a way to organize the configuration of the container. That way you won't be stuck with a single large file with all the container configurations in it. ## Creating a configuration contract

The easiest way to do this is with an interface. Why an interface? Because we're not interested in creating an object for configuring our dependency injection container. What we really want is to create a contract that tells other developers how they can configure it. This gives them more flexibility when trying to organize how they want to configure the container. It also makes sense because, as you'll see soon, these configuration class don't have any code that we want to reuse. ```
interface MyPlugin_ContainerConfigurationInterface
{
    /**
     * Modifies the given dependency injection container.
     *
     * @param MyPlugin_Container $container
     */
    public function modify(MyPlugin_Container $container);
}
```

But first, let's look at the interface itself! Above is the code for our `MyPlugin_ContainerConfigurationInterface` interface. The interface has a single method: `modify`. The role of the `modify` method in our `MyPlugin_ContainerConfigurationInterface` interface contract is pretty explicit. It expects to receive the `MyPlugin_Container` dependency injection container that we're configuring. And it'll make modifications to it. ## Implementing our configuration contract

Now that we have our `MyPlugin_ContainerConfigurationInterface` interface, we can look at how to use it. Let's imagine that our plugin has a specific component or system like an [event manager](https://carlalexander.ca/designing-system-wordpress-event-management/) or a [router](https://carlalexander.ca/designing-system-wordpress-routing/). A configuration class would look something like this: ```
class MyPlugin_ComponentConfiguration implements MyPlugin_ContainerConfigurationInterface
{
    public function modify(MyPlugin_Container $container)
    {
        $container['component_parameter'] = get_option('myplugin_component_parameter', 'default_value');

        $container['component_service'] = $container->service(function (MyPlugin_Container $container) {
            return new MyPlugin_ComponentClass($container['component_parameter']);
        });
    }
}
```

We have the `MyPlugin_ComponentConfiguration` class for our imaginary component. It implements the `MyPlugin_ContainerConfigurationInterface` interface that we created in the previous section. This means that the class also has the `modify` method required by the interface contract. The `modify` method itself adds two things to our dependency injection container. First, it adds the `component_parameter` which is an option stored in the WordPress database. We fetch it using the [`get_option`](https://developer.wordpress.org/reference/functions/get_option/) function. We then use that `component_parameter` parameter when creating our `component_service`. The `component_service` uses the `service` method that we created earlier. We pass it an anonymous function that creates a `MyPlugin_ComponentClass` object using the `component_parameter` parameter. ### On creating a WordPress configuration class

You might be wondering about the use of the `get_option` function in the `modify` method. Is it a good idea to use WordPress function like that when configuring a dependency injection container? The answer is yes! It's actually a great use of a dependency injection container. That's because it's a real challenge to design classes that don't use WordPress functions. In fact, it's the biggest struggle that WordPress developers have when they're trying to learn to use object-oriented programming. But with a dependency injection container, we can decouple your code from WordPress code. ```
class MyPlugin_WordPressConfiguration implements MyPlugin_ContainerConfigurationInterface
{
    public function modify(MyPlugin_Container $container)
    {
        $container['wordpress_database'] = $container->service(function (MyPlugin_Container $container) {
            global $wpdb;

            return $wpdb;
        });

        $container['wordpress_query'] = function (MyPlugin_Container $container) {
            return new WP_Query();
        };

        $container['wordpress_user'] = wp_get_current_user();
    }
}
```

The `MyPlugin_WordPressConfiguration` class above is an example of what we mean by that. We use it to modify our dependency injection container with things that would normally couple us to WordPress code. You can add WordPress related classes, parameters and services. The `MyPlugin_WordPressConfiguration` class has an example of each. First, we added the [`wpdb`](https://codex.wordpress.org/wpdb) class as a service. Next, we added an anonymous function which creates [`WP_Query`](https://carlalexander.ca/wordpress-adventurous-wp-query-class/) object each time that you ask for it. The last one stores the current user as returned by the [`wp_get_current_user`](https://codex.wordpress.org/wp_get_current_user) function. There's really no limit to what you can store inside your dependency injection container. Any time that you need something from WordPress, you should just add it to your dependency injection container. That way you won't need to use WordPress functions inside your classes anymore! (Well, at least, not as much!) ## Configuring a container using configuration objects

So, at this point, we broke down the configuration of our dependency injection container into configuration classes. But we still can't use these configuration objects with our `MyPlugin_Container` class. We need to add a way to pass to objects to it. ```
class MyPlugin_Container implements ArrayAccess
{
    // ...

    /**
     * Configure the container using the given container configuration objects.
     *
     * @param array $configurations
     */
    public function configure(array $configurations)
    {
        foreach ($configurations as $configuration) {
            $configuration->modify($this);
        }
    }

    // ...
}
```

That's the goal of the `configure` method shown above. The method has a single parameter: `configurations`. `configurations` is an array of configuration objects implementing the `MyPlugin_ContainerConfigurationInterface` interface. We use a [`foreach`](https://secure.php.net/manual/en/control-structures.foreach.php) loop to go through each `configuration` object. The loop itself just calls the `configuration` object's `modify` method. And we pass it the `this` pseudo-variable representing our container as the `container` argument. It's worth noting that we're not doing any validation on the content of the `configurations` array. We assume that the array will only contain objects implementing the `MyPlugin_ContainerConfigurationInterface`. But it's possible that you won't feel comfortable with that. If that's the case, you can add some validation inside the `foreach` loop to check if `configuration` variable implements the interface. (The easiest way to do that is with the `instanceof` operator.) ```
$container = new MyPlugin_Container();
$container->configure(array(
   new MyPlugin_ComponentConfiguration(), 
   new MyPlugin_WordPressConfiguration(), 
));
```

This brings us to how we'd use the `configure` method in practice. This is what this last code sample shows. We initialized our `MyPlugin_Container` class and then called the `configure` method. As an argument, we passed it an array with the two configuration objects that we created earlier. # A requirement with object-oriented programming

And this is how you can use dependency injection with WordPress! The whole thing revolves around the `MyPlugin_Container` class that we created. You can find the complete code for it below: ```
class MyPlugin_Container implements ArrayAccess
{
    /**
     * Values stored inside the container.
     *
     * @var array
     */
    private $values;

    /**
     * Constructor.
     *
     * @param array $values
     */
    public function __construct(array $values = array())
    {
        $this->values = $values;
    }

    /**
     * Configure the container using the given container configuration objects.
     *
     * @param array $configurations
     */
    public function configure(array $configurations)
    {
        foreach ($configurations as $configuration) {
            $configuration->modify($this);
        }
    }

    /**
     * Checks if there's a value in the container for the given key.
     *
     * @param mixed $key
     *
     * @return bool
     */
    public function offsetExists($key)
    {
        return array_key_exists($key, $this->values);
    }

    /**
     * Get a value from the container.
     *
     * @param mixed $key
     *
     * @return mixed|WP_Error
     */
    public function offsetGet($key)
    {
        if (!array_key_exists($key, $this->values)) {
            return new WP_Error('no_value_found', sprintf('Container doesn\'t have a value stored for the "%s" key.', $key));
        }

        return $this->values[$key] instanceof Closure ? $this->values[$key]($this) : $this->values[$key];
    }

    /**
     * Sets a value inside of the container.
     *
     * @param mixed $key
     * @param mixed $value
     */
    public function offsetSet($key, $value)
    {
        $this->values[$key] = $value;
    }

    /**
     * Unset the value in the container for the given key.
     *
     * @param mixed $key
     */
    public function offsetUnset($key)
    {
        unset($this->values[$key]);
    }

    /**
     * Creates a closure used for creating a service using the given callable.
     *
     * @param Closure $closure
     *
     * @return Closure
     */
    public function service(Closure $closure)
    {
        return function (MyPlugin_Container $container) use ($closure) {
            static $object;

            if (null === $object) {
                $object = $closure($container);
            }

            return $object;
        };
    }
}
```

This class might not seem like much to you. Most of it is just documentation anyways. (Because documentation is important!) But, as you use it, you'll come to realize how important it is to your success with object-oriented programming. That's because, as we mentioned in the introduction, you're going to create more and more classes as time goes on. It's the nature of object-oriented programming. (And a legitimate complaint that some developers have with it.) Managing all these classes in a sane way will become a real issue. This is when using a dependency injection container will go from something that's nice-to-have to a must-have. It's a good thing that using one isn't that complicated. You can just reuse this class and start building some configuration classes of your own.