Symfony2 - Como obter dinamicamente o Entity Manager de uma entidade Doctrine

Estamos construindo uma plataforma de criação de sites e CMS e com muitos sites diferentes de fornecedores e clientes, portanto, existem várias entidades do tipo de conteúdo, editadas por controladores genéricos e serviços auxiliares que não necessariamente (facilmente) sabem o que o gerente de entidade é para uma determinada entidade.

NOTA: Temos vários entityManagers para separar o acesso a diferentes bancos de dados, por exemplo, Global, Faturamento, Local, etc

Existem muitos casos em que precisamos detectar qual é o EntityManager da entidade. Por exemplo, temos um MediaHelper que associa dinamicamente a mídia de um banco de dados a campos correspondentes na entidade (isso não funciona com associações porque a Mídia precisa se conectar com literalmente qualquer entidade e você não pode ter esse tipo de associação dinâmica e não queremos cem associações diferentes).

A mídia está em um pacote gerenciado pelo EntityManager 'Local'. Mas a entidade pode estar em um EntityManager 'Global' (você não pode presumir que esteja no mesmo gerenciador de entidades). Portanto, precisamos detectar e persistir o gerente de entidade certo para a entidade certa.

Então, como você recomenda detectar dinamicamente o entityManager de uma entidade?

Método personalizado original

NOTA: a resposta aceita é uma solução muito melhor. Este é apenas aqui para fins de arquivo.

Aqui está uma solução simples que funciona. Mas não sei o suficiente sobre o Symfony e o Doctrine para saber se é uma má ideia? Alguém mais sabe? Caso contrário, não sei por que isso não estaria no núcleo, como um Utilitário de Doutrina.

Criei um serviço EntityHelper que injeta o serviço Doctrine nele:

gutensite_cms.entity_helper:
    class: Gutensite\CmsBundle\Service\EntityHelper
    arguments:
        - "@doctrine"

Então, no assistente de entidade, há uma função simples para obter o Gerenciador de Entidades para uma entidade (o config.yml já registra os pacotes configuráveis para os gerenciadores de entidades):

/**
 * Automagically find the entityManager for an entity. 
 * @param $entity
 * @return mixed
 */
public function getManagerForEntity($entity) {
    $className = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity));
    foreach (array_keys($this->doctrine->getManagers()) as $name) {
        if(in_array($className, $this->doctrine->getManager($name)->getConfiguration()->getMetadataDriverImpl()->getAllClassNames())) return $em;
    }
}

NOTA:Registro da doutrina # getAliasNamespace já faz algo quase idêntico a esse loop foreach, modifiquei a ideia para retornar o gerente da entidade em vez do namespace, por exemplo

public function getAliasNamespace($alias) {
    foreach (array_keys($this->getManagers()) as $name) {
        try {
            return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias);
        } catch (ORMException $e) {
        }
    }
    throw ORMException::unknownEntityNamespace($alias);
}

Atualização 21/10/15: Código de detecção de entidade atualizado por sugestão da @ Cerad.

questionAnswers(2)

yourAnswerToTheQuestion