Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

Most contrib modules have no reason to talk to the database directly instead a combination of configuration management, key value storage and the entity system should be used.

The feature here is useful for modules which wants to use proprietary features of a specific database and also for database drivers.

Before

In order to swap out the implementation of a service you could always change the container on compile() time:

class Example implements CompilerPassInterface {
  public function process(ContainerBuilder $container) {
    $container->set('views.date_sql', new Definition('Drupal\views\Plugin\views\query\PostgresqlDateSql'));
  }
}

After

The service you want to replace has to be tagged with backend_overridable and a backend specific override can be defined like this:

  views.date_sql:
    class: Drupal\views\Plugin\views\query\MysqlDateSql
    arguments: ['@database']
    tags:
      - { name: backend_overridable }
  pgsql.views.date_sql:
    class: Drupal\views\Plugin\views\query\PostgresqlDateSql
    arguments: ['@database']
    public: false

If Drupal is installed on PostgreSQL then pgsql.views.date_sql replaces the views.date_sql service.

In order to facilitate this easy override, services injecting the database service should be tagged as backend_overridable.

The default backend is defined by the container parameter default_backend. Setting it to the empty string disables this feature. If this parameter is not set then the values return by the current database Connection::driver() and Connection::databaseType() methods are used in this order.

Impacts: 
Site builders, administrators, editors
Module developers