Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wstrzykiwanie zależności jak w Spring
Forum PHP.pl > Forum > PHP > Object-oriented programming
WebCM
Podoba mi się podpinanie zależności w Springu. Komponenty tworzymy tak:

  1. public class MarkdownParser {
  2. public String parse(String input) { /* kod metody */ }
  3. }

Następnie wykorzystujemy je w tych klasach, gdzie są potrzebne:

  1. public class NewsController {
  2. @Autowired
  3. final NewsDAO newsDAO;
  4.  
  5. @Autowired
  6. final MarkdownParser markdownParser;
  7.  
  8. @GetMapping("/read/{id}")
  9. public String read(@PathVariable int id) {
  10. return markdownParser.parse(newsDAO.getById(id));
  11. }
  12. }

W Phalcon PHP też istnieje wstrzykiwanie zależności, ale w nieco mniej wygodnej formie. Otóż w pliku startowym musimy skonfigurować wszystkie komponenty (oprócz wstępnie dostępnych) w ten sposób:

  1. // Uwaga: jest set() i setShared()
  2. $di->set('markdownParser', function() {
  3. return new MarkdownParser;
  4. });

Klasa MarkdownParser dziedziczy po Phalcon\Mvc\User\Component

  1. class MarkdownParser extends \Phalcon\Mvc\User\Component {
  2. public function parse($input) { /* kod metody */ }
  3. }

Raz zarejestrowany komponent jest widoczny wszędzie i wynika z tego dużo problemów. Ponadto IDE nie wie o tym i bez dodatkowych zabiegów nie podpowiada składni.
  1. public class NewsController extends \Phalcon\Mvc\Controller {
  2. public function readAction($id) {
  3. $this->view->text = $this->markdownParser->parse(News::findFirstById($id));
  4. }
  5. }

Jak zaimplementować podpinanie zależności à la Spring w PHP? Macie jakiś pomysł?
em1X
Do takich celów służą moduły we frameworkach odpowiedzialne za Dependency Injection. Przykłądowo w przypadku Zend Framework 2 jest to klasa Service Manager.

Wystarczy dopisać jakiegoś rodzaju listener, który za pomocą Reflection zeskanuje dodaną do kontenera klasę i poszuka wszelkich adnotacji. Następnie potrzebna fabryka, która przy zwracaniu obiektów danego serwisu podepnie zadeklarowane za pomocą adnotacji serwisy.

Założeniem jest, że adnotowany serwis będzie pobierany wyłącznie za pomocą Service Managera. Wykonanie w kodzie zwyczajnie
  1. $service = new Service();
, spowoduje oczywiście, że zależności nie zostaną wstrzyknięte. Jeżeli zależy Ci na tym drugim, niezbędne byłyby jakieś natywne rozszerzenia do PHP.

Osobiście uważam, że nie powinieneś w ogóle takich adnotacji używać. Wiążesz w ten sposób nierozerwalnie swoje klasy z frameworkiem, podczas, gdy powinieneś starać się oderwać swój kod od frameworka w taki sposób, żeby był łatwo przenoszalny do innego projektu/frameworka i był od niego niezależny. Taka jest definicja dobrego kodu, pomijając oczywiście inne zasady typu SOLID/KIS etc.
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-2024 Invision Power Services, Inc.