2012-07-13 3 views
9

Symfony 2 Dependency Injection component을 새로운 PHP 5.4 traits과 함께 사용하는 방법을 찾으려고합니다.Symfony 2 : 의존성 삽입 및 특성

짧은 이야기를 짧게 만들기 위해 (사실 짧지는 않음) 내 프로젝트는 모든 고유 한 특정 생성자가있는 View 클래스를 분리했습니다. 각보기의 특성으로 정의되는 0 개 이상의보기 도우미, 사용할 수 있습니다

trait TranslatorHelper 
{ 
    /** 
    * @var Translator 
    */ 
    protected $translator; 

    /** 
    * @param Translator $translator 
    */ 
    protected function setTranslator(Translator $translator) 
    { 
     $this->translator = $translator; 
    } 

    /** 
    * @param string $text 
    * @return string 
    */ 
    public function translate($text) 
    { 
     return $this->translator->translate($text); 
    } 
} 

을 -

class UserEditView extends AbstractView 
{ 
    use TranslatorHelper; 

    public function __construct(User $user, UserEditForm $form) 
    { 
     // ... 
    } 
} 

내가 내 컨트롤러에 renderView()을하는 방법을 가지고 싶습니다, 그 세터을 수행 View 클래스에서 사용하는 모든 특성을 기반으로 주입보기를 렌더링하기 전에 :

class Controller 
{ 
    public function renderView(View $view) 
    { 
     // Check what traits are used by $view, and inject their dependencies 
     // {...} 


     // Then render the View 
     return $view->render(); 
    } 
} 

012와 함께이 작업을 수행하는 방법에 대한 아이디어구성 요소?

보기가 DI 컨테이너에 의해 생성되지 않지만 응용 프로그램 흐름의 어디에서나 생성 될 수 있다는 것이 주된 문제입니다. 종속성을 주입해야하는 것은 렌더링되기 전입니다.

마지막주의 사항 : 나는 Symfony 구성 요소와 관련이 없습니다. 다른 DI 컨테이너에있는 모든 리드도 감사 할 것입니다.

+0

AOP로 DI를 시도해 볼 수 있습니다 : https://github.com/schmittjoh/JMSAopBundle/blob/master/Resources/doc/index.rst 속성 및 인수의 주석으로 서비스를 자동 삽입 할 수 있습니다. – lisachenko

+0

문제는 뷰 헬퍼 (예 :'TranslatorHelper')를 일반적인 것으로 유지하려는 것이므로 이상적으로는 컨테이너에있는 종속성의 프로젝트 고유 ID를 포함하지 않아야합니다. – Benjamin

답변

4

이런 식으로 DI를 사용하는 데 특성이 사용되지 않는다고 생각합니다. 비슷한 시나리오에서 필요한 것은 필요한 서비스를 직접 주입하기 위해 특성을 구현하는 뷰 클래스에서 생성자 삽입을 사용하는 것입니다 (또는 세터가 좋을 수도 있습니다. 가능한 경우 생성자가 더 낫습니다).

클래스에 의해 구현 된 특성이 응용 프로그램이 실행되기 전에 정적으로 정의된다고 생각하면 동적 주입을 수행하기 위해 특성을 검사 할 필요가 없습니다. 실행하기 전에 어떤 서비스가 필요한지 알게 될 것입니다. 마치 구체적인 방법으로 인터페이스가있는 것처럼 변하는 것입니다.

+0

필자의 관점에서 볼 때, 필자는 View 생성자에 Helper 관련 종속성을 유지하려고합니다. (컨트롤러에서 View 생성자를 사용하여 뷰 자체에서 필요로하는 변수 만 전달하도록 명시 적으로 요청합니다. 도우미 걱정). 게다가, 나는 ~ 수백 개의 View 클래스를 가질 것이며, 모두 ~ 3 개의 뷰 헬퍼를 사용합니다. 따라서 특성 이름을 기반으로 주입 할 수 있어야합니다. 예를 들어,'TranslatorHelper' 특성을 사용하는 모든 클래스가'translator' 컨테이너 키가 가리키는 Translator를 사용할 것이라고 내 설정에서 정의하고 싶습니다. – Benjamin

+3

그런 경우 DI 태그 지정을 사용합니다. 태그를 정의하면 레지스터가 각 도우미 특성에 적합한 설정자 종속성을 수행하는 컴파일러가 전달됩니다. 최신 DIC 사용법 (예 : 컴파일러 통과 및 태그)에 관한 일부 문서는 최근에 Symfony 문서에 발표되었습니다. 그것은 특성을 기반으로 한 자동 주입이 아닙니다 (나는 그렇게하는 유일한 방법은 반사가 아주 느릴 것이라고 생각합니다). 그러나 이것은 깔끔하고 깨끗합니다. –