DEV Community

n0nag0n
n0nag0n

Posted on

Dependency Injection in Mako Framework for PHP

Dependency injection is so important in the architecture of your PHP app. When you start out with a tiny project, it's workable without it. When that project gets bigger, oh man! So let's go over Dependency Injection in the Mako Framework!

Understanding Dependency Injection

Let's say we have a Car class and this class needs an instance of an Engine class to work. Instead of creating an instance of the Engine class inside the Car class, we "inject" the Engine instance into the Car when we create it. This is the core idea of Dependency Injection.

Registering a Dependency

In Mako, we can register these dependencies in a container. The container is a special object that holds and manages instances of our classes. When we register a dependency, we're telling the container how to create an instance of a certain class.

Here's an example of how to register a dependency:

$container->register(EngineInterface::class, Engine::class);
Enter fullscreen mode Exit fullscreen mode

In this case, EngineInterface::class is the key we use to refer to the dependency in the container, and Engine::class is the concrete class that will be instantiated when we ask the container for this dependency.

Registering a Dependency with a Key

We can also associate a key with our dependency. This can make our code easier to read and write, and it also allows us to access our dependencies in a more flexible way.

$container->register([EngineInterface::class, 'engine'], Engine::class);
Enter fullscreen mode Exit fullscreen mode

In this example, we're associating the key 'engine' with our Engine::class dependency. Now we can retrieve our Engine instance from the container using either EngineInterface::class or 'engine' as the key.

Registering a Dependency with a Closure

Sometimes, creating an instance of a class might involve some complex logic or additional configuration. In these cases, we can use a closure to define how the instance should be created.

$container->register([WheelInterface::class, 'wheel'], fn ($container) => new Wheel('parameter value'));
Enter fullscreen mode Exit fullscreen mode

Here, we're telling the container to create a new instance of Wheel with 'parameter value' as an argument. The closure gives us a lot of flexibility when it comes to creating our instances.

Registering a Singleton Dependency

Sometimes, we want to ensure that there's only one instance of a certain class in our application. There are times like when you only want one guaranteed instance of a Database Connection no matter how many times you call a service from a container. This is known as a singleton. We can register a singleton dependency in the container like this:

$container->registerSingleton([EngineInterface::class, 'engine'], fn ($container) => new Engine('parameter value'));
Enter fullscreen mode Exit fullscreen mode

Now, every time we ask the container for the 'engine' dependency, it will always return the same instance of Engine.

Registering an Existing Instance

If we already have an instance of a class and we want to register it in the container, we can do so using the registerInstance method.

$container->registerInstance([WheelInterface::class, 'wheel'], new Wheel('parameter value'));
Enter fullscreen mode Exit fullscreen mode

This can be useful if we need to register an instance that was created outside of the container, or if we want to share a specific instance across different parts of our application.

Resolving a Dependency

Once we've registered our dependencies in the container, we can retrieve them using the get method. This is known as resolving a dependency.

$engine = $container->get(EngineInterface::class);
Enter fullscreen mode Exit fullscreen mode

Or using the optional key:

$engine = $container->get('engine');
Enter fullscreen mode Exit fullscreen mode

When we resolve a dependency, the container will give us an instance of the class associated with the given key. If the dependency was registered with a closure, the container will execute the closure to create the instance.

And that's it! You now know how to add a new dependency to the application container using the Mako PHP framework. Remember, the key to understanding Dependency Injection is practice, so don't hesitate to experiment with these concepts in your own projects. Happy coding!

Top comments (0)