symfony: Service with dots in names can't be used for service subscription

Symfony version(s) affected: 4.x.x, 5.x.x

Description
According to the coding standards multiple services for the same class can be divided in groups separated with dots, e.g. something.service_name

But for service subscribers there is a regular expression that does not allow dots, so aliases can’t be used as types, and a check that service type as FQCN exists

I have >20 services with same interface and different aliases, but there is no “main service” to assign an interface for - they are equal.

If I use a combination of an existing alias and an FQCN as a service type in a service subscriber while interface is not registered as a service, compiler throws an exception The service “My\CommandBus” has a dependency on a non-existent service “[FQCN]”.

Do I have to declare a boilerplate stub as service record with FQCN just to pass the check?

There are several hundreds of developers in a project, declaring an interface as a service will create unpredictable side effects for those who use it as a parameter type already.

How to reproduce

  1. declare a service by FQCN and an alias with different parameters with dots in a name
  my.sorted_set:
    class: DataStructures\Implementations\MysqlSortedSet
    arguments:
    - "dbServerName"
  re.sorted_set:
    class: DataStructures\Implementations\RedisSortedSet
    arguments:
    - "redisServerName"

  1. Declare a service subscription with
class CommandBus implements \Symfony\Contracts\Service\ServiceSubscriberInterface
{
    public static function getSubscribedServices()
    {
        return ['my.sorted_set'=>\DataStructures\SortedSetInterface::class];
    }
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (8 by maintainers)

Most upvoted comments

Binding on the service definition itself with an interface-service map solves the problem.

  Packages\CommandBus:
    tags:
      - {name: 'container.service_subscriber'}
    bind:
      DataStructures\SortedSetInterface: '@my.sorted.set'

I will try the named parameter binding, got it.

Thank you! 👍🏻

the regex applies to $type, not $key. Can you clarify the actual issue? It seems core uses the feature itself;

https://github.com/symfony/symfony/blob/367aa1df6caa2c739a58165ead81e7fe50e6599e/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php#L202-L207