# Creating a Dependency Injection (DI) Container

A while ago, I've created a [small PHP framework](https://github.com/lekoala/kaly). In order to adhere to modern practice (it even has basic middleware support even if I don't like them), I had to pick a DI container. The issue was: either there were too complicated, or too simple. And also, sometimes I like to reinvent the wheel.

## But what is a DI container exactly?

To make it simple, a DI container is a class used to instantiate other classes based on *definitions*. An interface has been defined in the [PSR-11 about Container interface](https://www.php-fig.org/psr/psr-11/).

## Why create my own

To be honest, it wasn't really the plan. I found out [devanych/di-container](https://github.com/devanych/di-container) and I was really impressed by the simplicity of it. But there were a few things I wanted to improve.

First, I wanted the DI container to fit in one single class. In order to do that, I had to convert the Exceptions to anonymous classes extending the base PSR interface.

And then, there were a couple of other features I wanted to have:

- Picking dependency by name if they returned the proper type
- Allow overriding distinct parameters
- Call methods after instantiation (not everything can be set in the constructor)

Actually, I managed to fit all that [under 300 LOC](https://github.com/lekoala/kaly/blob/master/src/Di.php) so I'm quite happy with the result. Of course, it's not as featured as PHP-DI or the Symfony DI component, but if 300 LOC do the job, why use more?

## What is a minimalist container?

I had [a discussion today on Reddit](https://www.reddit.com/r/PHP/comments/po1am2/capsule_3_clean_concise_composable_dependency/) about Capsule 3 that was recently released. The package shared a lot of my own goals:

- No cache (because it shouldn't be necessary)
- PHP configuration (no yml, special syntax, etc)
- Predictable output (always return the same instance once loaded)

But there was one key difference: it uses a Definition object instead of a plain array. While this may seem like an improvement, it's not perfect in my opinion:

- It makes the package more complicated than needed (and you need to test it)
- At the end of the day, you end up passing "magic" key/values to the argument method anyway, so it's not like the definition object help you to pick the right value (at least, a real config object would allow typed settings).

So... arrays it is for me.

## Conclusion

Well, I'm not sure where I'm going with this article :-) hopefully you picked some interesting stuff or it helped you think differently about the topic.

If you want to [learn more about my approach, you can also read the docs](https://github.com/lekoala/kaly/blob/master/docs/di.md)




