Skip to content

[RFC] Introduce "semantics": a way to make service ids meaningful by binding them to types+descriptions #27207

Closed
@nicolas-grekas

Description

@nicolas-grekas

Introduction

Some service ids are more important than others: they are like entry points for the features provided by core or third party bundles (or the app itself). Yet, we are missing a way to reliably identify them amongst all the other service ids that are here just to make things work.

The debug:container command used to use the public/private concept as a way to make this distinction, but now that all/most services are private, we know this was a broken hack (which has been removed in 4.1). Autowiring gave us a different perspective on the topic: the aliases we added to make it work are some of these meaningful identifiers. But there are more, like all the cache pools that users define in their configuration, or command buses, or logger channels, etc. - all sort of non-autowireable services that are still part of the useful services for users.

In #26142, @weaverryan tried to introduce "key services". This is another hint we're missing something, like a blind spot for a concept we didn't grasp yet. I'd like to introduce you to "semantics", which is a proposal I brainstormed about with @tgalopin and that IOHO could fill this hole.

Semantics

These meaningful services have 3 properties that make them special:

  • their id convey semantics: it is a meaningful string that hints the purpose of the service (e.g. "logger", or "bus.command", etc.);
  • we want to be able to enforce their type, so that 1. their id is bound to an abstraction and 2. they are made easy to discover and type-hint for;
  • their purpose is documented, so that people can know why and when they should use any of them.

These 3 properties should be independent from the actual definition of the services that provide them. For this reason, we need something new, independent from Alias and Definition instances.

Given these contraints and definitions, the proposal is to make "semantics" a first class concept.
Technically, one could create them like that:

Using the ContainerBuilder directly:

$container->setSemantics(string $id, array $types, string $description = null);

Using yaml:

semantics:
  cache.forecast:
    types: [Psr\Cache\CacheItemPoolInterface, Symfony\Component\Cache\Adapter\AdapterInterface]
    description: The cache pool where forecast-related items should be stored.

(the listed types should inherit from each others, so that this wouldn't allow creating new types that don't exist in PHP.)

Use cases

Provided with this additional semantics, we'll be able to:

This should not incur any burden on regular users as the concept should be manipulated only by bundle authors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRFC = Request For Comments (proposals about features that you want to be discussed)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions