Building a Pimple/Container from a YAML file


The last May I attended to the great deSymfony day conference in Barcelona. At speaker’s dinner I had a great conversation with Máximo Cuadros about Dependency Injection Containers. We discuss about the customisation of containers. I said that I prefer Symfony´s DIC instead of Pimple, mainly because its configuration with YAML (or even xml) files. But In fact we can customise Pimple/Containers with YAML files in a similar way than we do it with Symfony’s DIC. In this example we’re going to see one way to do it.

We can easily extend the Pimple/Container and add a function to load a YAML files, parse them and build the container. But doing this we’re violating various SOLID principles. First we’re violating the Open-Close principle, because to extend our Pimple/Container with the new functionality we are adding new code within an existing class. We’re also violating the Dependency Inversion Principle and our new Pimple/Container is going to be harder to maintain. And finally we’re obviously violating the Single Responsibility Principle, because our new Pimple/Container is not only a DIC, it’s also a YAML parser.

There’s another way to perform this operation without upsetting SOLID principles. We can use the Symfony’s Config component

The idea is simple. Imagine this simple application:

use Pimple\Container;

$container = new Container();
$container['name'] = 'Gonzalo';

$container['Curl'] = function () {
    return new Curl();
};
$container['Proxy'] = function ($c) {
    return new Proxy($c['Curl']);
};

$container['App'] = function ($c) {
    return new App($c['Proxy'], $c['name']);
};

$app = $container['App'];
echo $app->hello();

We define the dependencies with code. But we want to define dependencies using a yml file for example:

parameters:
  name: Gonzalo

services:
  App:
    class:     App
    arguments: [@Proxy, %name%]
  Proxy:
    class:     Proxy
    arguments: [@Curl]
  Curl:
    class:     Curl

As we can see we’re using a similar syntax than Symfony’s DIC YAML files.
Now, with our new library we can use the following code:

use Pimple\Container;
use G\Yaml2Pimple\ContainerBuilder;
use G\Yaml2Pimple\YamlFileLoader;
use Symfony\Component\Config\FileLocator;

$container = new Container();

$builder = new ContainerBuilder($container);
$locator = new FileLocator(__DIR__);
$loader = new YamlFileLoader($builder, $locator);
$loader->load('services.yml');

$app = $container['App'];
echo $app->hello();

Now our Pimple/Container is just a Pimple/Container nothing more. It doesn’t know anything about yaml, parsers and thing like that. It’s doesn’t have any extra responsibility. The responsibility of the parser falls on YamlFileLoader
You can see the library in my github account. It’s but one usage example of Symfony’s Config component. It only allows Yaml files, but it can be extended with Xml files adding a XmlFileLoader.

7 thoughts on “Building a Pimple/Container from a YAML file

    1. It’s just another one. The idea of this experiment came from a dinner conversation. I normally use Symfony’s one. I prefer it instead of pimple mainly because it’s more customisable and it allows me to define services with a yml instead of pimple’s way. But when I was saying that I realised that I also can parse a yml file and build a pimple container in the same way than I do with Symfony’s DIC. Anyway this yml2pimple builder is not the same than sf DIC’s. yml2pimple only implements a couple of functionalities (it’s just a minimal MVP). Maybe we can build a silex app from a yml file (given that silex extends pimple)

      1. I have made a new version of your yml2pimple with nearly 80-90% compatibility to my old symfony dic yml files. I needed this to move my silex application from two containers to only one container. i had to downgrade the required pimple version to 1.x because i have silex 1,2. but its easy to convert to pimple 2.x.

        give it a try if you want: https://github.com/td7650/yml2pimple

  1. i have updated the readme and the example to get a better understanding of all the new features.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.