Problem/Motivation
We would like a storage class that is decoupled from the actual table layout.
Proposed resolution
A separate factory encapsulating the table-layout logic that instantiates the table mapping. We could exploit per-entity-type services to make the factory swappable.
Every storage class can implement its own ::createInstance()
method and define its own dependencies and services. As long as we return an implementation of TableMappingFactoryInterface
, there is really no point in requiring the service string identifier to be fixed. For instance:
class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements SqlStorageInterface, ContentEntitySchemaHandlerInterface {
public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, FieldInfo $field_info, TableMappingFactoryInterface $table_mapping_factory) {
// ...
}
}
class NodeStorage extends ContentEntityDatabaseStorage {
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
$container->get('database'),
$container->get('entity.manager'),
$container->get('field.info'),
$container->get('node.table_mapping_factory')
);
}
}
class CommentStorage extends ContentEntityDatabaseStorage {
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
$container->get('database'),
$container->get('entity.manager'),
$container->get('field.info'),
$container->get('comment.table_mapping_factory')
);
}
}
Remaining tasks
Do it.
User interface changes
None.
API changes
Perhaps. Minor and largely non-disruptive if so. We would probably end-up changing the services passed to ContentEntityDatabaseStorage::__construct()