On Thursday 28th of August the hnDependencyInjectionPlugin was released on GitHub and packagist. Unfortunately I’ve been too busy to write this blog post about it since. When I got an e-mail yesterday about a new stargazer*, I decided it was time to blog about creating the hnDependencyInjectionPlugin.
So, what does this plugin do?
It’s a small Symfony 1 plugin, targeted at aiding the upgrade to Symfony 2. This upgrade is a big problem, because Symfony 2 is a complete rewrite of Symfony 1. With the plugin you can make the transition like this:
Upgrade in baby steps. Incrementally.
Some components are easier to integrate then others of course. In my personal experience you can start using the form component almost instantly. If you use Propel, it’s a nice idea to start replacing it with Doctrine. It’s also interesting to include are the config component and security component. The last one I didn’t try yet, but there should be something possible there.
Lets look a bit closer at how it works :-).
To make it work you have to pass in two things: the bundles that you have to use, and the configuration to configure them. The main output of the plugin is a (compiled) Dependency Injection (DI) container. So how does one get from a list of bundles + configuration to a DI container?
If you look at what a bundle is, this starts to make sense. Last week I was at a meetup of the Symfony user group NL, where I found one particular interesting definition of a bundle on a slide:
A bundle is an extension to the service container.
That is from a presentation on the book release of A year with Symfony**. So this plugin makes sure all bundles are registered, the configuration is read, and the resulting container is built.
A small warning is appropriate though: if you’re still using Symfony 1 in a reasonably sized application, go for the complete upgrade***. If you’re programming into a ridiculously sized application, then this plugin might be for you.
The process of creating the hnDependencyInjectionPlugin
Creating the hnDependencyInjectionPlugin started on the route of the form-twig-bridge. The elegance of using only the bare minimum of components. Composing them to fit the way I want. Maximizing the use of the PHP ecosystem.
The original goal was to make an awesome light-weight, forward-compatible, Doctrine plugin. When I was busy gluing the components, it got more and more complicated. Also, I was including more and more components.
At about the same time I was upgrading the form-twig-bridge to use Symfony 2.3. The officially supported API stayed very stable, but due to a bugfix done the gluing code had to be updated as well. Suddenly the code I had written for the Doctrine plugin didn’t seem so future proof at all!
Surely, there must be an easier way?
Back to the drawing board
So instead of building a doctrine plugin, I built a way to use bundles from Symfony 2 instead. The plugin was able to take advantage of all the Symfony 2 glue code. At least, once I started being a little bit more generous about which components I allowed as a dependency.
The plugin still a slight preference to doctrine. For example, the propel configuration is generated based on the doctrine config.
No more creating special purpose plugins, this is truly a one size fits all plugin. Provided you have a legacy app using Symfony 1, that you would like to port to Symfony 2. Or one that you’d like to use some of the Symfony 2 goodness in ;-).
* Hey Kielabokkie. Good to know you’re still watching from the other side of the planet!
** This is a book written by Matthias Noback. It looks like a very nice book, can’t wait till it will be printed.
*** Combining Symfony 1 with a (partial) Symfony 2 installation could give some overhead. My personal benchmarks showed a page-slowdown of ~10%.