Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][Symfony2] Dependency injection container
Forum PHP.pl > Forum > PHP > Frameworki
Orzeszekk
Do czego on tak naprawdę służy?

Z tego co zrozumialem to ma on zlikwidowac problem ze gdy zmieniamy nazwe klasy to musimy zmienic x nazw w kodzie, oraz pozwala oddzielic singleton od jego implementacji (niby mamy taki singleton, tworzony raz, dostepny globalnie ale jak chcemy to mozemy utworzyc jego obiekt recznie na potrzeby testu jednostkowego i nawet cos tam wstrzyknac jakies parametry w konstruktor?). No i po za tym jest wg mnie mało wygodny w uzyciu bo musimy wpisywac nazwy stringami w ktorych mozemy sie pomylić (literówka) i żadne IDE nam nie wskaże takiego błędu, a SF z jakiegos powodu nie chce uzywac stałych, tylko zamiast tego uzywa stringow.

Klasa dependency injectora nie jest chyba zbyt duza, a poswiecono jej bardzo obszerny rozdzial w ksiazce, no i na potrzeby DI stworzono całą konfiguracje w Yamlu ktora wyglada jak nowy jezyk programowania.

Czy do czegos jeszcze sie przydaje ten dependency injection container? Czy wprowadza jakąś dużą innowacje do kodowania (duzo ludzi sie nim zachwycalo) czy to po prostu taki testowalny singleton?
Crozin
Cytat
Do czego on tak naprawdę służy?
Do tego żeby się nie pochlastać przy ręcznym zarządzaniu dziesiątkami komponentów aplikacji i setkami, jak nie tysiącami, zależnościami dla nich.

Cytat
Z tego co zrozumialem to ma on zlikwidowac problem ze gdy zmieniamy nazwe klasy to musimy zmienic x nazw w kodzie
Nie, od tego to masz IDE.
Cytat
oraz pozwala oddzielic singleton od jego implementacji
Nie potrafię nawet zrozumieć co to niby oznacza "oddzielić singleton od implementacji"

Cytat
No i po za tym jest wg mnie mało wygodny w uzyciu bo musimy wpisywac nazwy stringami w ktorych mozemy sie pomylić (literówka) i żadne IDE nam nie wskaże takiego błędu, a SF z jakiegos powodu nie chce uzywac stałych, tylko zamiast tego uzywa stringow.
A jak miałoby niby wyglądać użycie tych stałych skoro DIC to twór, którego elementy są znane dopiero w czasie kompilacji?
Cytat
Klasa dependency injectora nie jest chyba zbyt duza, a poswiecono jej bardzo obszerny rozdzial w ksiazce, no i na potrzeby DI stworzono całą konfiguracje w Yamlu ktora wyglada jak nowy jezyk programowania.
W Sf2 DIC-em możesz zarządzać przez pliki XML (preferowane), YAML oraz "czyste PHP". A poświęcono jej sporo bo jest to narzędzie wykorzystywane przez pół frameworka.

Cytat
Czy wprowadza jakąś dużą innowacje do kodowania (duzo ludzi sie nim zachwycalo) czy to po prostu taki testowalny singleton?
Innowację? Nie bardzo. Takie coś jak DIC wymyślono już dobrych naście lat temu. To po prostu pierwsza dobra i popularna adaptacja takiego narzędzia dla PHP.

O tym co to jest DI i DIC napisano już wiele, nawet bardzo wiele więc nie będziemy tutaj powtarzać. Google: [PHP/Java] dependency injection [container] (dla Javy jest znacznie więcej materiału więc nic nie stoi na przeszkodzie by z nich korzystać, a w dodatku implementacje DIC dla PHP w dużym stopniu bazują na Java'owych więc nie będzie problemu z adaptacją - ostatecznie wątek nie jest związany z żadnym językiem)
Orzeszekk
Czyste PHP w symfony2 jest z lekka szalone, ma taka renundancje ze i tak trzeba yamla uzywac nawet jak go ktos nie lubi.


Czyli ten DIC to zamiast "hardkodowac" sobie w projekcie 10 razy linijke kodu $mailer = new MyMailer();, lub co gorsza, $mailer = MyMailer::get(); tworzę wytwór jakim jest $mailer = $this->get('my_mailer'); a w configu symfony ustawiam my_mailer: { class: "MyMailer" } czy jak tam sie to pisało, i jesli chce mi sie zmienic mailera to po prostu zmieniam go w configu a nie po kolei we wszystkich miejscach? To jest ta główna korzysc tak?

skoro symfony2 to w zasadzie kompilator PHP to nie widze powodu dla którego nie mogłby wygenerowac w jakims pliku php inkludowanym w bootstrapie wszystkich stałych z nazwami moich serwisów, żebym mógł sobie w IDE wpisać SERVICE_... a ono by mi uzupełniło, i co ważniejsze wyłapało głupie literówki. wiem ze stałe to zbedny overhead ale literówki to rowniez overhead tylko ze predkosci pisania ,a skoro symfony tak bardzo integruje sie z APC to zawsze tam mogloby zapisac set stałych z nazwami serwisów co spowodowaloby ze tylko raz bylyby tworzone.

oddzielic singleton od implementacji - znalazlem na stronie z jakimis refaktoryzacjami porade ze jesli juz musisz uzyc singletonu to by część "pracującą" wrzucić do jednej klasy, której instancje mozna stworzyc normalnie na potrzeby unit testu, i stworzyc druga klase opakowujaca tego workera w singleton, ktory bedzie sobie normalnie dzialal w programie. o to mi chodzilo.

no i przy automatycznych zmianach nazw wszystkie IDE do php sie czasami mylą, nie ma idealnego pod tym względem. a znajdz/zamien potrafi narobic sporo bałaganu smile.gif
Crozin
Głównym celem DIC-a jest całościowe przygotowanie "usługi". Zauważ, że w większości przypadków nie wystarczy $a = new A();. Trzeba jeszcze jakieś tam parametry w konstruktorze / setterach przekazać, a każdy z tych parametrów sam w sobie może wymagać dokładnie takiej samej konfiguracji, gdzie i owa konfiguracja również może wymagać własnej konfiguracji - sporo tego co nie?

Weźmy za przykład wspomnianego przez Ciebie mailera. Taka usługa potrzebować będzie kilku zależności i kilku parametrów konfiguracyjnych. W końcu wysłanie maila to dosyć skomplikowana operacja, która może zostać zrealizowana na wiele sposobów. Nagle zamiast prostego new Mailer() robi się coś w stylu:
  1. $a = new A();
  2. $b = new B('param1', 'param2');
  3. $c = new C($a, 22);
  4. $c->setABC('def', array('a' => 'a', 'b' => 'b', 'c' => 'c'));
  5.  
  6. $mailer = new Mailer($b, $c, true);
  7. $mailer->setSth(null);
  8.  
  9. // dopiero tutaj $mailer to w pełni funkcjonalny obiekt
Trochę nieciekawa perspektywa zważywszy na fakt, że dostęp do takiej usługi jest potrzebny w co najmniej kilkunastu miejscach w normalnej aplikacji. Znacznie wygodniej przenieść sobie całą konfigurację usługi gdzieś w inne miejsce by nie zaśmiecać sobie normalnego kodu takimi potworkami, prawda? Kilka osobnych plików XML (od biedy YAML), grupujących usługi z obrębu aplikacji to zdecydowanie przyjemniejsze środowisko do pracy.
Oczywiście fakt istnienia DIC-a nie oznacza, że nigdy nie wolno Ci użyć "czystego" $myService = new MyService(123);.

Co do tych stałych... nie przesadzaj z tymi literówkami. Akurat w tym przypadku wystąpienie jakiejkolwiek to w zasadzie gwarancja wysypania się całej aplikacji. Jednak jeżeli naprawdę tak Ci na tym zależy sam możesz sobie takie wygenerować - to dosłownie chwila roboty. W głównym Bundle'u swojej aplikacji dodaj CompilerPass'a:
  1. namespace MyApp\RootBundle\DependencyInjection\Compier;
  2.  
  3. use ...;
  4. use ...;
  5. use ...;
  6.  
  7. class MyPass implements CompilerPassInterface {
  8. public function process(ContainerBuilder $container) {
  9. $services = array_keys($container->getDefinitions());
  10. $output = "<?php \n";
  11.  
  12. foreach ($services as $service) {
  13. $output .= sprintf("define('%s', '%s');\n", 'SERVICE_' . strtoupper(str_replace(array('.', '-'), array('_', '_'), $service)), $service);
  14. }
  15.  
  16. file_put_contents('/path/to/file', $output);
  17. }
  18. }
A w bootstrapie dołącz sobie plik /path/to/file

Cytat
oddzielic singleton od implementacji - znalazlem na stronie z jakimis refaktoryzacjami porade ze jesli juz musisz uzyc singletonu to by część "pracującą" wrzucić do jednej klasy, której instancje mozna stworzyc normalnie na potrzeby unit testu, i stworzyc druga klase opakowujaca tego workera w singleton, ktory bedzie sobie normalnie dzialal w programie. o to mi chodzilo.
Rozumiem już o co Ci chodzi, ale nazwa "oddzielic singleton od implementacji" to kompletny bełkot, więc więcej tego nie używaj. wink.gif

Cytat
no i przy automatycznych zmianach nazw wszystkie IDE do php sie czasami mylą, nie ma idealnego pod tym względem. a znajdz/zamien potrafi narobic sporo bałaganu
No niestety narzędzia dla PHP są naprawdę wątpliwej jakości w większości. Ale cóż... PHP to bardzo dynamiczny język co właściwie uniemożliwia istnienie takich narzędzi, a i o społeczności skupionej wokoło tego języka w samych superlatywach mówić nie można. wink.gif

PS. W Symfony2 od co najmniej pół roku kompletnie nic nie robiłem, więc mogło się tam coś pozmieniać - za podany gotowiec nie ręczę.
ano
Cytat(Orzeszekk @ 5.02.2012, 20:40:10 ) *
Czyste PHP w symfony2 jest z lekka szalone, ma taka renundancje ze i tak trzeba yamla uzywac nawet jak go ktos nie lubi.


Co ma yaml do 'redundancji'? ;] Poza tym, kto Ci broni pisać wszystkie configi jako *.php? Jeżeli, Ci tak wygodniej to zamiast yamla/xmla pisz php...

Co do podpowiadania 'magicznych rzeczy' to może zainteresuje Cię ten plugin do Eclipse: http://symfony.dubture.com/ .
Potrafi naprawdę sporo!
- Podpowiada serwisy (Controller::get('...'))
- trasy w routingu (również w czasie tworzenia kodu twiga {{ path(...) }} )
- a nawet ścieżki do szablonów (Controller::render(...));.
- i jeszcze trochę wink.gif
Orzeszekk
zdecydowalem sie juz na PHPStorma i z niego nie schodzę. Cały rok szukalem takiego narzedzia. Napisane tak jakby na tworcach IDE nie zrobilo wrazenia to ze PHP to język dynamiczny.
Ma refaktoryzacje dostepne w zendzie (rename, extract method, extract variable, extract constant), przy projekcie ok 50 tys linijek kodu pokazanie code assist po nacisnieciu ctrl+spacja trwa ulamek sekundy a nie jak w eclipsie 2s, czy w netbeansie 5+s, no i nie sypie sie jak zend ktory choc ma wszystkie wymagane funkcje to z deka muli jak eclipse, kosztuje mnósto pieniedzy i pomimo ze probowalem sie do niego 3 razy przekonac to zawsze padł po nie wiecej niz tygodniu (albo nawalal wyjatkami jak szalony albo w ogole sie nie chcial wlaczyc). głównie cieszą mnie auto refaktoryzacje, bo fajnie miec kod bez copiego pasta i magicznych zmiennych a ręcznie to troche czasu zajmuje, no i pomyłeczki..
a tak to skrot klawiaturowy i samo sie robi. No ale wybór IDE to kwestia dyskusyjna.
Moze do storma tez taki plugin jak dupture jest. Poszukam.

no wlasnie chcialem powiedziec ze yaml ma duza mniejsza renundancje niz PHP w konfigach, tam zrobic cos to 2 wyrazy a w PHP to czasem kilka linijek. No i błąd w yamlu jest wylapany przez sf od razu, a kod php wygenerowany przez sf jest na pewno juz poprawny. a blad w recznie napisanym w php configu moze wyjsc po czasie. i z rozsądku uzywam Yamla choc za nim nie przepadam smile.gif


Czyli jakbym sobie zrobił MailerFactory ktora by produkowala wszystkie mozliwe rodzaje mailerów, i do niego rejestr tych mailerów to bym nie musiał uzywac DICa bo wyszlo by na prawie to samo, ale za pomocą DICa jest szybciej prosciej czytelniej wygodniej i lepiej?
Crozin
Cytat
Czyli jakbym sobie zrobił MailerFactory ktora by produkowala wszystkie mozliwe rodzaje mailerów, i do niego rejestr tych mailerów to bym nie musiał uzywac DICa bo wyszlo by na prawie to samo, ale za pomocą DICa jest szybciej prosciej czytelniej wygodniej i lepiej?
W pewnym sensie tak. DIC to ogólnie rzecz biorąc nic innego jak dosyć sporych rozmiarów rejestr usług, które są wytwarzane i ewentualnie niszczone według pewnych reguł ustalonych na etapie kompilacji.

W sumie możesz sobie podejrzeć jaki kod jest generowany na podstawie tych XML-i i innych YAML-ów, w pliku /.../cache/classes-XXXX.php czy czymś w ten deseń. Porównaj sobie później definicję z XML-a z wygenerowanym kodem - da Ci to jakiś obraz na to z czym to się je.
Orzeszekk
Nie no w sumie juz wszystko jasne smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.