Jak Mogę uzyskać dostęp do usługi poza kontrolerem za pomocą Symfony2?

Buduję witrynę, która w dużej mierze opiera się na zewnętrznym API, więc pomyślałem, że warto byłoby spakować opakowanie API jako usługę, jednak zaczynam odnajdywać przypadki, w których przydałoby się mieć dostęp do niego poza kontrolerem, takim jak w repozytorium podmiotu. W związku z tym przydatne byłoby uzyskanie dostępu do wartości konfiguracyjnych poza kontrolerem (podobnie jak w repozytorium encji).

Czy ktoś może mi powiedzieć, czy jest to możliwe a jeśli nie, czy istnieje sugerowane podejście do tego rodzaju rzeczy?

Thanks for any help

Author: Habeeb Perwad, 2011-05-25

2 answers

Dystrybucja Symfony opiera się w dużej mierze na iniekcji zależności. Oznacza to, że zazwyczaj zależności są wstrzykiwane bezpośrednio do obiektu przez konstruktor, ustawiacze lub za pomocą innych środków(np. odbicie nad właściwościami). Usługa owijania API jest wtedy zależnością dla innych obiektów aplikacji.

Biorąc to pod uwagę, raczej trudno byłoby wprowadzić tę usługę do konstruktora repozytorium encji, ponieważ wymaga ona już innych parametrów i myślę, że nie byłoby możliwe ich wstrzyknięcie ze względu na sposób, w jaki żądamy repozytorium dla podmiotu.

To, co możesz zrobić, to utworzyć kolejną usługę, która będzie odpowiedzialna za wykonanie pracy, którą miałeś wykonać w repozytorium encji. W ten sposób będziesz mógł wstrzyknąć menedżera encji, który zostanie użyty do pobrania repozytorium encji, usługi niestandardowej, a także innej usługi przechowującej twoje wartości konfiguracyjne (istnieją inne sposoby udostępniania konfiguracji wartości).

Facebook facebook helper Service ([1]}w moim przypadku używam serwisu Facebook helper, który zawija połączenia API Facebooka. Ta usługa jest następnie wstrzykiwana tam, gdzie jej potrzebuję. Moje repozytorium encji jest odpowiedzialne tylko za wywołanie bazy danych, więc otrzymuje tylko potrzebne argumenty, a nie całą zależność. W ten sposób nie otrzyma helpera, a jedynie argumenty potrzebne do wykonania żądania, na przykład identyfikator użytkownika Facebook. Moim zdaniem jest to sposób, ponieważ uważam, że repozytorium encji nie powinno mają zależności od takich obiektów pomocniczych.

Oto mały przykład użycia YAML jako konfiguracji:

# app/config/config.yml
services:
  yourapp.configuration_container:
    class: Application/AcmeBundle/Common/ConfigurationContainer
    # You could inject configurations here      

  yourapp.api_wrapper:
    class: Application/AcmeBundle/Service/ApiWrapperService
    # Inject other arguments if needed and update constructor in consequence    

  yourapp.data_access:
    class: Application/AcmeBundle/Data/Access/DatabaseAccessService
    arguments: 
      entityManager: "@doctrine.orm.entity_manager"
      apiWrapperService: "@yourapp.api_wrapper"
      configuration: "@yourapp.configuration_container"

# Application/AcmeBundle/Common/ConfigurationContainer.php
public ConfigurationContainer
{
   public function __construct()
   {
       // Initialize your configuration values or inject them in the constructor
   }
}        

# Application/AcmeBundle/Service/ApiWrapperService.php
public ApiWrapperService
{
   public function __construct()
   {
       // Do some stuff
   }
}

# Application/AcmeBundle/Data/Access/DatabaseAccessService.php
public DatabaseAccessService
{
    public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)
    {
        ...
    }
}

Znak at ( @ ) w konfiguracji.plik yml oznacza, że Symfony powinien wprowadzić inną usługę, o identyfikatorze zdefiniowanym po znaku at, a nie prostym łańcuchu znaków. Dla wartości konfiguracyjnych, jak powiedziałem wcześniej, istnieją inne sposoby osiągnięcia tego samego celu, takie jak użycie parametrów lub rozszerzenia pakietu. W przypadku rozszerzenia pakietu można bezpośrednio zdefiniować wartości konfiguracyjne do config.yml i Twój Pakiet by je przeczytał.

Podsumowując, powinno to dać ci ogólną ideę wstrzykiwania usług. Tutaj mała lista dokumentacji na ten temat. Wiele linków używa definicji usługi XML zamiast definicji YAML, ale powinieneś być w stanie zrozumieć je dość łatwo.

  1. Symfony Official DI
  2. Artykuły Fabien Potenier NA DI
  3. Artykuły Richarda Millera na temat DI (Sprawdź jego blog dla innych artykułów DI)

Zwróć uwagę, że konfiguracja, którą podaję, działa dla beta1 Symfony2. Nie zaktualizowałem jeszcze do Beta2, więc może być coś, co nie działa tak, jak jest w wersji Beta2.

Mam nadzieję, że to pomoże Ci określić ostateczne rozwiązanie twojego problemu. Nie wahaj się zadawać innych pytań, jeśli chcesz wyjaśnić lub cokolwiek innego.

Pozdrawiam, Matt

 74
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-10 11:36:11

Chciałbym zawinąć tego typu zachowanie w usłudze Symfony (jak menedżer). nie wprowadzałbym żadnych parametrów ani logiki do repozytoriów encji, ponieważ powinny one być używane głównie do pobierania danych za pomocą zapytań object manager. Chciałbym umieścić logikę w usługach i jeśli usługa, wymaga dostępu do bazy danych wywoła repozytorium entity do pobrania danych.

 0
Author: shacharsol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-23 21:31:06