2016-01-26 1 views
0

В нашем приложении мы определили репозитории услуги, как в следующем примере:Symfony2 DI ленивой службы и typehinting

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

Так что мы могли бы внедрить его в сфере услуг, где мы только необходимы конкретные репозитории вместо целого объекта менеджер. Это было легче проверить и сделать наши услуги менее связанными.

EG:

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

С типом конструктора намекая это зависимости:

<?php 

use AppBundle\Entity\CompanyRepository 

public function __construct(CompanyRepository $repo) 
... 

Теперь этот список начинает расти большим, и я думал об определении этих репозиториев lazy, чтобы получить некоторые характеристики ,

например:

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

На первый взгляд, казалось, на работу. Но после некоторого тестирования я обнаружил, что тип намекая, кажется, была сломана, определив эти услуги как lazy

Пример Exception я получаю после определения этих репозиториев ленивых:

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

Я честно удивлен это исключение, как это кажется, что это simlar случай использования, как описано официальной документации Symfony 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.

является ли это что-то поправимо или это недостаток использования ленивые услуги.

Я, хотя о:

  • Тип интерфейса намекая может решить эту проблему? (Есть некоторые работы, но я могу жить с этим)
  • Не использовать ленивые услуги и принять «медленное» приложение (Будет печальная новость)
  • Stop инъекционной конкретные репозитории и вернуться к инъекции EntityManager (ощущению действительно грязными и буду перерыв во многих тестах)

Cookies for buts!

+0

Я не пользовался ленивыми услугами репозитория. Он работает, если вы удалите typehint? – Cerad

ответ

3

У вас есть ошибка в определении службы репозитория. Заменить class: AppBundle\Entity\Company на class: AppBundle\Entity\CompanyRepository.

+0

О, человек, которого я бы пропустил, даже если бы я прочитал его 100 раз. Сейчас я чувствую себя таким глупым, спасибо! – RVandersteen

+0

Интересно. Обычно класс: не имеет значения, когда используется фабрика. Но я полагаю, что для ленивых сервисов класс используется для генерации прокси. Любопытно узнать, действительно ли использование ленивых репозиториев улучшает производительность. Сами прокси-серверы добавляют значительные накладные расходы, и я действительно не думаю, что хранилища все тяжелы. Но кто знает. – Cerad

+0

Некоторые быстрые испытания с использованием сканера apache привели к улучшению +/- 150-200 мс при разрешении. (Это была только 1 api конечная точка). Выглядит многообещающе, но мне нужно будет сделать больше тестов, чтобы прийти к твердому выводу. – RVandersteen