it-swarm.dev

Bagaimana saya bisa mengakses layanan di luar pengontrol dengan Symfony2?

Saya sedang membangun situs yang sangat bergantung pada API pihak ketiga jadi saya pikir masuk akal untuk mengemas pembungkus API sebagai layanan, namun saya mulai menemukan contoh di mana akan berguna untuk memiliki akses ke sana di luar pengontrol seperti di repositori entitas. Juga terkait dengan itu akan berguna untuk bisa mendapatkan akses ke nilai-nilai konfigurasi di luar controller (lagi seperti dalam repositori entitas).

Adakah yang bisa memberi tahu saya jika ini mungkin dan jika tidak ada pendekatan yang disarankan untuk melakukan hal semacam ini?

terima kasih atas bantuannya

51
pogo

Distribusi Symfony sangat bergantung pada injeksi ketergantungan. Ini berarti bahwa biasanya, dependensi disuntikkan langsung ke objek Anda melalui konstruktor, setter atau melalui cara lain (seperti refleksi atas properti). Layanan bungkus API Anda kemudian menjadi ketergantungan untuk objek lain dari aplikasi Anda.

Karena itu, akan agak sulit untuk menyuntikkan layanan ini dalam konstruktor repositori entitas karena sudah memerlukan beberapa parameter lain dan saya pikir tidak mungkin untuk menyuntikkan mereka karena cara kami meminta repositori untuk entitas.

Yang bisa Anda lakukan adalah membuat layanan lain yang akan bertanggung jawab melakukan pekerjaan yang akan Anda lakukan di repositori entitas. Dengan cara ini, Anda akan dapat menyuntikkan manajer entitas, yang akan digunakan untuk mengambil repositori entitas, Anda layanan kustom dan juga layanan lain yang memegang nilai konfigurasi Anda (Ada cara lain untuk berbagi nilai konfigurasi).

Dalam kasus penggunaan saya, saya menggunakan layanan pembantu Facebook yang membungkus panggilan API Facebook. Layanan ini kemudian disuntikkan di mana saya membutuhkannya. Repositori entitas saya hanya bertanggung jawab untuk melakukan panggilan basis data sehingga hanya menerima argumen yang diperlukan dan bukan seluruh ketergantungan. Dengan demikian, itu tidak akan menerima helper tetapi hanya argumen yang diperlukan untuk melakukan permintaan, misalnya, id pengguna Facebook. Menurut pendapat saya, ini adalah cara untuk melakukannya karena saya pikir repositori entitas seharusnya tidak memiliki ketergantungan pada objek pembantu seperti itu.

Berikut contoh kecil menggunakan YAML sebagai konfigurasi:

# 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)
    {
        ...
    }
}

Tanda at (@) dalam file config.yml berarti bahwa Symfony harus menyuntikkan layanan lain, setelah id didefinisikan setelah tanda at, dan bukan string sederhana. Untuk nilai konfigurasi, seperti yang saya katakan sebelumnya, ada cara lain untuk mencapai tujuan yang sama seperti menggunakan parameter atau ekstensi bundel. Dengan ekstensi bundel, Anda bisa menentukan nilai konfigurasi langsung ke config.yml dan bundel Anda akan membacanya.

Sebagai kesimpulan, ini harus memberi Anda gambaran umum tentang layanan injeksi. Berikut daftar kecil dokumentasi tentang masalah ini. Banyak tautan menggunakan definisi layanan XML daripada definisi YAML tetapi Anda harus dapat memahaminya dengan mudah.

  1. Symfony Official DI
  2. Artikel Fabien Potencier tentang DI
  3. Artikel Richard Miller di DI (Lihat di blog-nya untuk artikel DI lainnya)

Perhatikan bahwa konfigurasi yang saya berikan berfungsi untuk Beta1 dari Symfony2. Saya belum memperbarui ke Beta2 sehingga mungkin ada beberapa hal yang tidak berfungsi karena mereka ada dalam versi Beta2.

Saya harap ini akan membantu Anda menentukan solusi akhir untuk masalah Anda. Jangan ragu untuk bertanya pertanyaan lain jika Anda ingin klarifikasi atau apa pun.

Salam, Mat

74
Matt

Saya akan membungkus perilaku semacam ini dalam layanan Symfony (seperti manajer) . Saya tidak akan menyuntikkan parameter atau logika ke repositori entitas, karena mereka terutama harus digunakan untuk mengambil data menggunakan query manajer objek . Saya akan meletakkan logika di layanan dan jika layanan, memerlukan akses database, itu akan memanggil repositori entitas untuk mengambil data.

0
shacharsol