Skip to content

[DependencyInjection] Load services from Composer #48065

Closed as not planned
Closed as not planned
@renanbr

Description

@renanbr

Description

We can import many services using the resource key, and fill exclude or include entries with a glob pattern to determine which classes will be considered.

The problem: Maintaining glob patterns is hard in projects with custom folder structures (e.g. DTO placed in many namespaces). It may be worst if the application holds many namespaces.

What if the framework provides an additional way to import services?

The basis of the idea is:

  • Users declares services explicitly1
  • The framework import these services2

1 The framework could provide a class-level attribute called AsService which could act semantically as When(env: '*').

2 The framework can rely on the namespaces/folders declared in composer.json to determine the classes to analyze.

Example

As result, this configuration could work for any kind of directory structure:

// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Routing\Attribute\AsRoutingConditionService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\AsService;
use Symfony\Component\DependencyInjection\Attribute\AsTaggedItem;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use Symfony\Component\DependencyInjection\Attribute\When;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

return static function(ContainerConfigurator $configurator) {
    // default configuration for services in *this* file
    $services = $configurator->services()
        ->defaults()
            ->autowire()
            ->autoconfigure()
    ;

    // registers classes under PSR-4 namespaces from a Composer file
    $services->loadFromComposer('../composer.json')
        ->hasAttribute(AsCommand::class)
        ->hasAttribute(AsController::class)
        ->hasAttribute(AsDecorator::class)
        ->hasAttribute(AsEventListener::class)
        ->hasAttribute(AsMessageHandler::class)
        ->hasAttribute(AsRoutingConditionService::class)
        ->hasAttribute(AsService::class)
        ->hasAttribute(AsTaggedItem::class)
        ->hasAttribute(Autoconfigure::class)
        ->hasAttribute(When::class)
        ->instanceOf(AbstractController::class)
    ;
};

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions