• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Symfony DI component - integracja z Doctrine

VPS Starter Arubacloud
0 głosów
608 wizyt
pytanie zadane 5 kwietnia 2020 w PHP przez Assasz Nałogowiec (30,460 p.)
zamknięte 5 kwietnia 2020 przez Assasz

Witajcie!

Korzystam w projekcie z komponentu Symfony DI oraz Doctrine (standalone, żaden flex). Tak wygląda mój composer.json:

"require": {
    "php": "^7.2",
    "cakephp/collection": "^3.8",
    "doctrine/orm": "^2.6",
    "filp/whoops": "^2.1",
    "symfony/config": "^4.2",
    "symfony/dependency-injection": "^4.2",
    "symfony/dotenv": "^4.2",
    "symfony/http-foundation": "^4.2",
    "symfony/yaml": "^4.0",
    "symfony/serializer": "4.2"
  }

Konfiguracja serwisów:

services:
  _defaults:
    autowire: true      
    autoconfigure: true 
    public: false       

  Rmr\:
    resource: '../src/*'
    exclude: '../src/{Entity, Http}'

  # próbowałem również tak podpiąć klasy Doctrine
#  Doctrine\ORM\:
#    resource: '../vendor/doctrine/orm/lib/Doctrine/ORM'
#    exclude: '../vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver'

Problem polega na tym, że w żaden sposób nie mogę wstrzyknąć klas Doctrine, które są mi potrzebne do inicjalizacji repozytoriów.

Repozytoria:

abstract class AbstractEntityRepository extends EntityRepository implements EntityRepositoryInterface
{
// to konstruktor wzięty żywcem z ServiceEntityRepository z DoctrineBundle

//    /**
//     * AbstractEntityRepository constructor.
//     * @param ManagerRegistry $registry
//     * @param string $entityClass The class name of the entity this repository manages
//     */
//    public function __construct(ManagerRegistry $registry, string $entityClass)
//    {
//        $manager = $registry->getManagerForClass($entityClass);
//
//        if ($manager === null) {
//            throw new \LogicException(sprintf(
//                'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
//                $entityClass
//            ));
//        }
//
//        parent::__construct($manager, $manager->getClassMetadata($entityClass));
//    }
}

class ClientRepository extends AbstractEntityRepository implements ClientRepositoryInterface
{
//    /**
//     * ClientRepository constructor.
//     * @param ManagerRegistry $registry
//     */
//    public function __construct(ManagerRegistry $registry)
//    {
//        parent::__construct($registry, Client::class);
//    }
}

Wersja z konstruktorami daje taki błąd:

Cannot autowire service \"Rmr\\Repository\\ClientRepository\": argument \"$registry\" of method \"__construct()\" references interface \"Doctrine\\Persistence\\ManagerRegistry\" but no such service exists. Did you create a class that implements this interface?

Wersja bez konstruktorów:

Cannot autowire service \"Rmr\\Repository\\ClientRepository\": argument \"$em\" of method \"Doctrine\\ORM\\EntityRepository::__construct()\" references interface \"Doctrine\\ORM\\EntityManagerInterface\" but no such service exists. Did you create a class that implements this interface?

Także moje pytanie wygląda tak: jak mogę zintegrować te dwa komponenty, aby korzystać z klas Doctrine w taki sam sposób, jak to wygląda w Symfony? Tutaj nie mogę korzystać z żadnych Symfonowych bundli i się zastanawiam, jak to sam ogarnąć.

Dzięki za pomoc i pozdrawiam.

komentarz zamknięcia: Rozwiązanie w komentarzu.

1 odpowiedź

0 głosów
odpowiedź 5 kwietnia 2020 przez Assasz Nałogowiec (30,460 p.)

Ok, rozwiązałem to. Wystarczy napisać i wstrzyknąć adapter zamiast samego EntityManagera/ManagerRegistry:

class EntityManagerAdapter implements EntityManagerAdapterInterface
{
    /** @var EntityManager */
    private $entityManager;

    /**
     * @return EntityManagerInterface
     */
    public function getManager(): EntityManagerInterface
    {
        return $this->entityManager;
    }
}

class ClientRepository extends AbstractEntityRepository implements ClientRepositoryInterface
{
    /**
     * ClientRepository constructor.
     * @param EntityManagerAdapter $managerAdapter
     */
    public function __construct(EntityManagerAdapter $managerAdapter)
    {
        parent::__construct($managerAdapter, Client::class);
    }
}

abstract class AbstractEntityRepository extends EntityRepository implements EntityRepositoryInterface
{
    /**
     * AbstractEntityRepository constructor.
     * @param EntityManagerAdapter $managerAdapter
     * @param string $entityClass
     */
    public function __construct(EntityManagerAdapter $managerAdapter, string $entityClass)
    {
        $manager = $managerAdapter->getManager();

        parent::__construct($manager, $manager->getClassMetadata($entityClass));
    }
}

Zostawiam dla potomnych ;)

Podobne pytania

0 głosów
1 odpowiedź 239 wizyt
pytanie zadane 10 maja 2020 w PHP przez XiverKi Bywalec (2,050 p.)
0 głosów
0 odpowiedzi 356 wizyt
pytanie zadane 6 lutego 2021 w PHP przez mat19 Obywatel (1,580 p.)
0 głosów
1 odpowiedź 632 wizyt
pytanie zadane 17 lutego 2021 w Algorytmy przez CSSoup Mądrala (6,460 p.)

92,980 zapytań

141,943 odpowiedzi

321,189 komentarzy

62,307 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...