Uwagi: Począwszy od wersji 2.8, Symfony warunkiem
autowire: true
do konfiguracji usług, a od wersji 3.3, Symfony warunkiemalias
(zamiastautowire_types
) do aliasu konkretny obiekt do interfejs automatycznego wtrysku zależności do "kontrolerów jako usług". Jest też pakiet, który pozwala na autowirowanie dla metod "działania" kontrolera, chociaż odsunąłem się od tego i skupiłem się bardziej na odmianie wzorca ADR (który jest zasadniczo pojedynczą klasą "działania" z metodą interfejsu i nie wrzucanie ładunków metod działania w ramach jednej klasy, która ostatecznie doprowadzi do architektonicznego koszmaru). To jest faktycznie to, czego szukałem przez te wszystkie lata i teraz już nie potrzebuję "wciągać" przyzwoitego wtryskiwacza zależnego od rekursywności (auryn), ponieważ obecnie struktura obsługuje to, co powinno mieć cztery lata wcześniej. Zostawię tę odpowiedź tutaj na wypadek, gdyby ktoś chciał śledzić kroki, które zrobiłem, aby zobaczyć, jak działa jądro i niektóre opcje dostępne na tym poziomie.Symfony - zmiana jak kontrolery są wystąpienia i wykonywane
Uwaga: Chociaż to pytanie przede wszystkim skierowany Symfony 3, powinno być również istotne dla użytkowników Symfony 2, jak logika jądro wydaje się nie zmieniły się znacznie.
Chcę zmienić sposób tworzenia kontrolerów w Symfony. Logika ich powstawania znajduje się obecnie w HttpKernel::handle, a dokładniej, HttpKernel::handleRaw. Chcę zastąpić call_user_func_array($controller, $arguments)
z własnym wtryskiwaczem wykonującym tę konkretną linię.
opcje próbowałem dotąd:
- Rozszerzanie
HttpKernel::handle
z własną metodą, a następnie o to nazywane przez symfony
http_kernel:
class: AppBundle\HttpKernel
arguments: ['@event_dispatcher', '@controller_resolver', '@request_stack']
Minusem jest to, że z powodu handleRaw
jest Prywatne, nie mogę go rozszerzyć bez hackowatej refleksji, więc musiałbym skopiować i wkleić tonę kodu.
- Tworzenie i rejestracji nowego kontrolera resolverowi
controller_resolver:
class: AppBundle\ControllerResolver
arguments: []
To była zasadnicza nieporozumienie miałem więc pomyślałem, że to udokumentować tutaj. Zadaniem przelicznika jest rozstrzygnięcie: , gdzie, aby znaleźć kontroler jako wywoływalny. To jeszcze nie zostało jeszcze wywołane. Jestem bardzo zadowolony z tego, jak Symfony korzysta z tras od routes.yml
i wykrywa klasę i metodę, aby wywołać kontroler jako wywoływalny.
- Dodanie detektora zdarzeń na
kernel.request
kernel.request:
class: MyCustomRequestListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 33 /** Important, we'll get to why in a minute **/ }
Przyjrzeniu na Http Kernel Component Documentation, widzimy, że ma następujący typowy cel:
dodać więcej informacji Żądanie, zainicjuj części systemu lub zwróć odpowiedź, jeśli to możliwe (np. warstwa bezpieczeństwa, która odmawia dostępu).
Pomyślałem, że poprzez utworzenie nowego słuchacza, używając mojego własnego wtryskiwacza do tworzenia mojego kontrolera, a następnie zwraca odpowiedź w tym słuchacza, by ominąć resztę kodu, który tworzy instancję kontrolera. To jest to, co chcę! Ale jest w tym poważna wada:
Profil Symfony nie pojawia się ani nic z tego, to tylko moja odpowiedź i tyle. Nie żyje. odkryłem, że mogę przełączyć priorytet od 31 do 33 i to przełączanie między moim kodu i Symfonys i wierzę, że to dlatego, że od słuchacza routera priority. Czuję, że schodzę tu na złą drogę.
- Słuchanie w wydarzeniu kernel.controller.
Nie, to pozwala mi zmienić wpłacone która zostanie wywołana przez call_user_func_array()
, a nie jak regulator jest faktycznie instancja, która jest mój cel.
mam udokumentować moje pomysły, ale jestem na zewnątrz. Jak mogę osiągnąć następujące?
- zmienić sposób kontrolery są wystąpienia, a następnie stracony, a konkretnie
call_user_func_array()
który jest w krwawej metody prywatnej (dzięki Symfony) - Spadek z powrotem do domyślnego kontrolera instancji jeśli kopalnia nie działa
- Pozostawić wszystko jeszcze pracować zgodnie z oczekiwaniami, jak załadunku profiler
- umieć ten pakiet z rozszerzeniem dla innych użytkowników
Dlaczego chcę to zrobić?
Kontrolery mogą mieć wiele różnych metod dla różnych okoliczności i każda metoda powinna być w stanie wpisać podpowiedź dla tego, czego wymaga indywidualnie, a nie mieć konstruktora, który bierze wszystkie rzeczy, z których niektóre mogą nawet nie być używane, w zależności od metody kontrolera wykonany. Kontrolery nie są zgodne z zasadą pojedynczej odpowiedzialności i są "przypadkiem skrajności obiektu". Ale oni są tym, kim są.
Chcę zastąpić sposób tworzenia kontrolerów za pomocą mojego własnego rekursywnie wstawianego wtryskiwacza, a także sposobu ich wykonywania, ponownie za pomocą introspekcji rekurencyjnej za pośrednictwem mojego wtryskiwacza, ponieważ domyślny pakiet Symfony nie ma tej funkcji. Nawet z najnowszą opcją usługi "autowire" w Symfony 2.8+.
Nie wyobrażam sobie wielkiego stołu, ale refleksja może być kluczem do zastąpienia tej prywatnej metody. http: //blag.kazeno.net/development/access-private-protected-properties ten artykuł może ci pomóc. – FZE
@ FeyyazEsatoğlu Mój pierwszy punkt wypunktowania wyjaśnia, w jaki sposób nie chcę korzystać z refleksji (próbowałem już tego i nie lubiłem). – Jimbo
oops, przepraszam, ominąłem to. – FZE