Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Symfony]DependencyInjection/Extension.php i DefinitionDecorator, definicja dekoratora bez klasy?
koszykarze
post 17.02.2016, 22:51:50
Post #1





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


uczę się Services, DI, compilerPass, Extension, Configuration. Patrzę w FOSElasticaBundle.

Patrzę w DependencyInjection/FOSElasticaExtension.php

  1. class FOSElasticaExtension extends Extension
  2. {
  3. public function load(array $configs, ContainerBuilder $container)
  4. {
  5. //code
  6.  
  7. $this->loadClients($config['clients'], $container);
  8.  
  9. //code
  10. }
  11.  
  12. /**
  13.   * Loads the configured clients.
  14.   *
  15.   * @param array $clients An array of clients configurations
  16.   * @return array
  17.   */
  18. private function loadClients(array $clients, ContainerBuilder $container)
  19. {
  20. foreach ($clients as $name => $clientConfig) {
  21. $clientId = sprintf('fos_elastica.client.%s', $name);
  22. $clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
  23. $clientDef->replaceArgument(0, $clientConfig);
  24. $clientDef->addTag('fos_elastica.client');
  25. $container->setDefinition($clientId, $clientDef);
  26.  
  27. $this->clients[$name] = array(
  28. 'id' => $clientId,
  29. 'reference' => new Reference($clientId),
  30. );
  31. }
  32. }



chwilę wcześniej uczyłem się o dekoratorach w service container. Wynikało z tego, że jednak klasa definiowanego dekoratora musi być napisana też w php. Czyli co, powyżej sobie dynamicznie tworzę definicje serwisów tj dekoratory bez podania klasy?

a może tworząc obiekt DefinitionDecorator, wrzucając do konstruktora id dekorowanej definicji ('fos_elastica.client_prototype') to dekorator dziedziczy klasę dekorowanego serwisu?

Ten post edytował koszykarze 18.02.2016, 04:48:56
Go to the top of the page
+Quote Post
lukaskolista
post 18.02.2016, 16:30:23
Post #2





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Cytat
Wynikało z tego, że jednak klasa definiowanego dekoratora musi być napisana też w php
A niby w czym ma być napisana?

Jakbyś spojrzał w źródło klasy DefinitionDecorator to byś zobaczył, że wcale nie trzeba podać klasy - dekorator definicji to nie taki dosłowny dekorator w kontekście wzorca projektowego.

Edit:
W końcu zapomniałem wytłumaczyć o co chodzi:
W Symfony można tworzyć abstraktyjne usługi czyli takie, których instancje nie są tworzone, a które służą do tworzenia innych definicji. To właśnie programowalny odpowiednik tego, co można równie dobrze zrobić w konfiguracji, jednak w tym przypadku umieszczenie tego akurat w rozszerzeniu pakietu ma konkretne przyczyny.

Ten post edytował lukaskolista 18.02.2016, 16:33:22
Go to the top of the page
+Quote Post
koszykarze
post 18.02.2016, 19:31:14
Post #3





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


W pętli tworzone są abstrakcyjne usługi, które służą do tworzenia innych definicji.

Na razie nie ogarniam. Wrócę do tego później.



Ten post edytował koszykarze 19.02.2016, 03:32:34
Go to the top of the page
+Quote Post
lukaskolista
post 19.02.2016, 07:28:27
Post #4





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


fos_elastica.client_prototype jest usługą abstraktycją zdefiniowaną w konfiguracji usług, natomiast w pętli tworzone są "normalne" usługi na podstawie konfiguracji ale już tej zdefiniowanej w Configuration.php
Go to the top of the page
+Quote Post
koszykarze
post 20.02.2016, 20:20:49
Post #5





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


(wrzuciłbym te pytania do przedszkola, bo to pewnie niezrozumienie podstaw OOP, ale nie będę otwierał nowego tematu).

- jak to jest, że usługę abstrakcyjną (fos_elastica.client_prototype) implementuje zwykła, a nie abstrakcyjna klasa ?

- w tej pętli "normalnym" usługom czyli tworzonym definicjom dekoratorów nie przypisuje się klas DefinitionDecorator::setClass(). No więc wracam do podstawowego pytania tego wątku, jak to rozumieć, że definiuję usługę (dekorator) bez podania klasy? Bo nie bardzo widzę by to się działo gdzieś później w Extension czy CompilerPass.
Go to the top of the page
+Quote Post
lukaskolista
post 20.02.2016, 22:04:51
Post #6





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Proste: Definicja != klasa

Definicja abstrakcyjnej usługi może bazować na nieabstrakcyjnej klasie.
Podobnie też definicja usługi może dziedziczyć po innej definicji usługi, która bazuje na klasie finalnej (klasa jest finalna, ale usługa to tylko definicja obiektu tej klasy, który będzie utworzony - DEFINICJA OBIEKTU, NIE KLASY).
Definicja to definicja, klasa to klasa i nie możesz utożsamiać z sobą tych 2 bytów.

Usługa abstrakcyjna to pojęcie podobnego poziomu, co usługa publiczna/prywatna oraz usługa leniwa. Czy klasy są publiczne/prywatne, a tym bardziej czy istnieją klasy leniwe? Nie smile.gif

Ten post edytował lukaskolista 20.02.2016, 22:06:40
Go to the top of the page
+Quote Post
koszykarze
post 22.02.2016, 02:05:45
Post #7





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


zgłupiałem całkiem. Długo głowiłem się czy to
  1. $defDec = new DefinitionDecorator('bar');
  2. $defDec->addMethodCall('setBaz','baz');
  3. $container->setDefinition('foo', $defDec);

oznacza to:
  1. services:
  2. bar
  3. calls:
  4. - [setBaz ,[baz]]
  5. foo
  6. decorates: bar

czy to:
  1. services:
  2. foo
  3. decorates: bar
  4. calls:
  5. - [setBaz ,[baz]]
  6. bar


aż w innych projektach zobaczyłem:
  1. $defDec = new DefinitionDecorator('bar');
  2. $container
  3. ->setDefinition(sprintf('foo'), $defDec)
  4. ->addMethodCall('setBaz','baz');



wreszcie doszedłem, że to przecież wszystko jedno.

Ten post edytował koszykarze 22.02.2016, 03:45:42
Go to the top of the page
+Quote Post
lukaskolista
post 22.02.2016, 12:30:10
Post #8





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Wcale nie wszystko jedno, różnica jest kolosalna. W pierwszym przykładzie metodę setBaz() wywołujesz na usłudze bar, a w drugim na usłudze foo.
Go to the top of the page
+Quote Post
koszykarze
post 22.02.2016, 15:43:54
Post #9





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Bardziej mi chodziło z punktu widzenia użycia dekoratora 'foo' - że to wszystko jedno.
Serwis dekorowany 'bar' zostaje niezmieniony.
Dla ścisłości, czyli ten drugi jest poprawny, tak?


Jeszcze miałbym pytanie z beczki obok.
w kodzie z pierwszego postu w pętli jest fragment:
  1. $clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
  2. $clientDef->replaceArgument(0, $clientConfig);

typem pierwszego argumentu konstruktora klasy serwisu 'fos_elastica.client_prototype' jest array(), a $clientConfig w pętli raz pochodzi od arrayNode innym razem scalarNode
edit: a dobra, to dzięki ->prototype('array')

Ten post edytował koszykarze 22.02.2016, 18:39:53
Go to the top of the page
+Quote Post
lukaskolista
post 23.02.2016, 12:35:37
Post #10





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Cytat
Dla ścisłości, czyli ten drugi jest poprawny, tak?
Oba są poprawne w zależności od tego, na którym obiekcie chcesz wykonać metodę setBaz()
Go to the top of the page
+Quote Post
koszykarze
post 23.02.2016, 16:15:13
Post #11





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


(nie chciałem już grzebać tego tematu, ale...) chyba nie piszemy o tym samym.

Ty pisząc "oba", "pierwszy" i "drugi" chyba masz na myśli fragment kodu nr 1 i 4 z Post #7.
Ja pisząc "wszystko jedno" mam na myśli, że dla kodu nr 1 serwisy 2 i 3 nie różnią się.

(ale nie brnijmy, już możesz zostawić ten temat)
Go to the top of the page
+Quote Post
lukaskolista
post 24.02.2016, 09:39:19
Post #12





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Mamy na mysli to samo (2 i 3 z #7) i się różnią smile.gif ale jak chcesz to możemy już w to nie brnąć.
Go to the top of the page
+Quote Post
koszykarze
post 24.02.2016, 18:29:41
Post #13





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 10.10.2015
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


brnijmy. (ja tu pobieram darmowy kurs, lekko zasugerowałem, że możesz już to olać bo ten temat zaczynam robić o wszystkim. Inna rzecz, że ta akurat kwestia nie jest chyba kluczowa). (Kluczowe dla mnie z tego tematu to załapanie, że serwis to nie klasa, faktycznie tak go utożsamiałem, i z tą myślą czytałem dziesiątki stron dokumentacji, blogi o DI, Services CompilerPass itp. Że to mniej więcej taka ładnie opakowana klasa, którą tak fajnie można w kontrolerze wywołać. Teraz rozumiem serwis(definicję) mniej więcej jako taki w pół utworzony obiekt. Że w tym kontenerze robię to, co i tak musiałbym zrobić w kontrolerze zaraz po, czy zaraz przed utworzeniem obiektu. To tak mocno upraszczając.)

brnijmy. Skoro tworząc definicję dekoratora w service container, i tak później w projekcie wywołuję nazwę serwisu dekorowanego to jakie znaczenie ma, z postu #7, czy methodCall jest wywoływany dla serwisu foo czy bar?
Go to the top of the page
+Quote Post
lukaskolista
post 25.02.2016, 13:47:29
Post #14





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Ma to znaczenia bardzo duże.

Implementacja przykładowej metody setBaz na usłudze Foo może być zupełnie inna, niż na usłudze Bar.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.03.2024 - 09:19