Buy

Configuration Loading and Type-Hinting

So just like with routing files, services.yml isn’t magically loaded by Symfony: something needs to import it.

When the bundle was generated, an EventExtension class was created for you.

This class is mostly useful for third-party bundles, but one thing it does by default is load the services.yml file:

// src/Yoda/EventBundle/DependencyInjection/EventExtension.php
// ...

public function load(array $configs, ContainerBuilder $container)
{
    // ...
    // this was all generated when we generated the bundle
    $loader->load('services.yml');
}

If you don’t have this “Extension” class in your bundle, no problem! In fact, delete the entire DependencyInjection directory. Now, just import your services.yml file from inside config.yml:

# app/config/config.yml
imports:
    # ...
    - { resource: "@EventBundle/Resources/config/services.yml" }

You could also rename services.yml to anything else. As you can see, the name isn’t important.

Note

The point is that any file that defines a service must be imported manually. This can be done via the special “extension” class of a bundle or simply by adding it to the imports section of config.yml or any other configuration file.

Refresh! More CSV Downloading!

Type-Hinting

There’s one more thing in our service that’s bothering me. The first argument to the constructor is the entity manager object, but we’re not type-hinting it. Type-hinting is optional, but I like doing it because it gives me better errors and gives me auto-completion in PhpStorm.

So what is the class for the entity manager service? One way to find out is to use container:debug but pass it the service name:

php app/console container:debug doctrine.orm.entity_manager

It says that it’s just an “alias” for a different service. So let’s look up that one:

php app/console container:debug doctrine.orm.default_entity_manager

Great! Now we can add a type-hint for the argument. And by the way, a lot of times I just guess the class name and let PhpStorm mind trick ... I mean auto-complete the use statement for me. It’s lazy, but it almost always works:

// src/Yoda/EventBundle/Reporting/EventReportManager.php
// ...

use Doctrine\ORM\EntityManager;

class EventReportManager
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }
}

If you’re not too comfortable with this, don’t worry. This is optional, but a good practice to get into.

Leave a comment!

  • 2016-08-12 weaverryan

    Hi Daria!

    Oh man, you were digging nicely! The *Extension and Configuration classes *can* be quite complex. But, they're also used almost exclusively by third-party, shared bundles. What I mean is: you should not have to build any of these classes for your code (in the Symfony 3 tutorial, we *no* longer create an Extension class - it's not needed).

    However, it *is* really cool to at least understand how these work - it'll help you reverse engineer what core and 3rd party bundles are doing - which makes you dangerous :). Check out this tutorial: http://knpuniversity.com/scree.... Actually, it's probably even deeper than you're asking about, but at the very least, this chapter - http://knpuniversity.com/scree... - talks about the purpose of these extension classes, by walking through the TwigExtension.

    The Configuration class is actually a bit simpler to understand (they're tough to write, but not to understand). These are defining the valid configuration that you're allowed to have in config.yml for a specific bundle. For example, try running:


    bin/console debug:config twig

    This will dump an example of all of the config that you can use under the "twig" key in configuration files. To build this tree, it's actually reading the Configuration class that's inside of the TwigBundle (https://github.com/symfony/sym.... So, these classes are just defining a big tree of the config that is valid for that bundle. And by reading it, you can learn a bit more about what are valid/invalid keys and (sometimes) what they do :).

    Anyways, that's a quick intro - it's pretty advanced stuff, but it's also super geeky and super fun.

    And I'll pass your nice words to our other "helpers" here - Leanna and Victor!

    Cheers!

  • 2016-08-11 Daria

    Hi Ryan,

    I got curious and took a look at the DependencyInjection/Configuration.php file that's used in the EventExtension class. It uses something called TreeBuilder. I've come across this TreeBuilder thingy regularly while reading the docs, but every time I do, my understanding sort of all falls apart and I'm blocked (or intimidated). Any chance of there being a short intro/explanation *knp style* to it to help me get going further?

    Cheers, and thank you both (and any helpers involved in these projects).