Nicolas Grekas Ryan Weaver
Contributed by Nicolas Grekas and Ryan Weaver in #21289 and #22680

Symfony 3.3 will introduce lots of features to simplify the way you work with services in your applications, such as simpler configuration and autoconfig. This article explains the last big feature related to Dependency Injection: PSR-4 based service discovery and registration.

The idea is to look for PHP classes in some given directories and register them as services if their namespaces meet the PSR-4 naming syntax. This feature is configured using the resource option, which accepts a directory path or a Glob expression to match multiple directories. Example:

1
2
3
4
services:
    App\:
        resource: ../src/{Controller,Command}
        # ...

This config looks for PHP files in the src/Controller/ and src/Command/ directories of the application, infers the PSR-4 class names from those files and uses class_exist() to check that they exist before registering those classes as Symfony services (using the class FQCN as the service id).

This feature is so convenient that Symfony Flex uses it by default in the app.yaml config file that will be used in Symfony 4 applications:

1
2
3
4
5
6
7
8
9
10
11
services:
    # ...

    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../../src/{Command,Form,EventSubscriber,Twig,Security}'

    App\Controller\:
        resource: '../../src/Controller'
        public: true
        tags: ['controller.service_arguments']

If your application contains lots of directories, you can include all of them using a * value in the resource option and then use the exclude option to exclude some directories if needed:

1
2
3
4
5
6
7
8
services:
    # ...

    AppBundle\:
        # discover services in all AppBundle/ sub-directories...
        resource: '../../src/AppBundle/*'
        # ... except in those matching this Glob expression
        exclude: '../../src/AppBundle/{AppBundle.php,Entity}'
Published in #Living on the edge