RVandersteen
RVandersteen

Reputation: 2137

Symfony2 DI of lazy service and typehinting

In our application, we defined repositories as services like the following example:

company.repository:
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company

So that we could inject it in services where we only needed specific repositories instead of the whole entity manager. It was easier to test and made our services less coupled.

E.G:

company.service:
    class: AppBundle\Services\CompanyService
    arguments:
        - @company.repository

With the constructor type hinting it's dependencies:

<?php

use AppBundle\Entity\CompanyRepository

public function __construct(CompanyRepository $repo)
...

Now this list is starting to grow large and I was thinking of defining those repositories as lazy to gain some performance.

E.G:

company.repository:
    lazy: true
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company

At first sight, it seemed to work. But after some testing I found that the type hinting seems to have been broken by defining those services as lazy

An example Exception I receive after defining those repositories as lazy:

Catchable Fatal Error: Argument 1 passed to AppBundle\EventListener\CompanyIdRequiredListener::__construct() must be an instance of AppBundle\Entity\CompanyRepository, instance of AppBundleEntityCompany_000000002d9713890000000167592edede1aa99e97f8c6a4a84b995db8a0c1e9 given

I'm honestly surprised by this exception as it seems that this is a simlar use case as described by the official Symfony documentation here

In some cases, you may want to inject a service that is a bit heavy to instantiate, but is not always used inside your object. For example, imagine you have a NewsletterManager and you inject a mailer service into it. Only a few methods on your NewsletterManager actually use the mailer, but even when you don't need it, a mailer service is always instantiated in order to construct your NewsletterManager.

Is this something fixable or is this a drawback of using lazy services.

I've though about:

Cookies for thoughs !

Upvotes: 0

Views: 342

Answers (1)

Sergey Fedotov
Sergey Fedotov

Reputation: 921

You have error in the repository service definition. Replace class: AppBundle\Entity\Company with class: AppBundle\Entity\CompanyRepository.

Upvotes: 3

Related Questions