Flazzo memiliki fokus utama untuk menambah nilai bisnis Anda.

Blog

Menulis Kode Lebih Baik: Injeksi Ketergantungan Symfony

16954037-thumb.jpg
Blog

Menulis Kode Lebih Baik: Injeksi Ketergantungan Symfony

[ad_1]

Injeksi ketergantungan (DI) digunakan secara luas untuk mengelola dependensi kelas dan menghindari masalah yang mungkin timbul dari penggunaan dependensi secara implisit. Sebagian besar kerangka kerja modern memiliki dukungan asli untuk fungsionalitas DI atau mungkin menggunakan pustaka pihak ketiga untuk ini. Pada artikel ini, kami akan menjelaskan implementasi DI pada framework Symfony.

Symfony menggunakan service container yang kompatibel dengan PSR-11 untuk menyimpan dan mendapatkan layanan. Kontainer layanan mengetahui semua layanan terdaftar dan dependensinya dan dapat menyediakan instance layanan yang diperlukan yang sudah diinisialisasi dan dibuat dengan benar.

Penciptaan layanan

Layanan adalah kelas dengan properti, metode, konstanta, dll. Setelah membuat kelas, kita perlu mendeklarasikan properti private/protected yang akan menerima layanan yang disuntikkan. Ada dua cara untuk mengisi properti ini: menggunakan konstruktor atau menggunakan metode penyetel. Pendekatan konstruktor adalah yang paling populer, biasanya digunakan saat membuat layanan. Namun, DI juga dapat digunakan dengan panggilan penyetel.

Pendekatan konstruktor diilustrasikan dalam contoh di bawah ini:

namespace App\Services;

class SmsService {
    private $gateway;

    public function __construct(SmsGatewayInterface $gateway)
    {
        $this->gateway = $gateway;
    }
}

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        arguments:
            - '@sms.gateway'

Pendekatan setter dapat digunakan ketika dependensi ditambahkan dengan suatu sifat, yang dapat menyediakan properti dan setter. Untuk menggunakan pendekatan ini, tambahkan a 'calls' bagian ke pernyataan layanan, seperti yang ditunjukkan di bawah ini:

namespace App\Services;

class SmsService {
    private $gateway;

    public function setGateway(SmsGatewayInterface $gateway)
    {
        $this->gateway = $gateway;
    }
}

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        calls:
            - [setGateway, ['@sms.gateway']]

Pendekatan ini berguna dalam kasus di mana ketergantungan ditambahkan dengan stroke atau Anda memiliki ketergantungan melingkar dan perlu mengelolanya. Namun, metode DI ini tidak disarankan; biasanya pendekatan konstruktor lebih dari cukup.

Layanan publik dan swasta

Symfony memungkinkan layanan ditandai sebagai ‘publik’ atau ‘pribadi’. Layanan publik dapat diakses langsung dari wadah layanan saat runtime. Meskipun tidak disarankan untuk mengakses layanan dengan cara ini, jika Anda harus mendeklarasikan layanan sebagai publik, seperti yang ditunjukkan di bawah ini:

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        public: true
        arguments:
            - '@sms.gateway'

Anda dapat mengakses layanan publik menggunakan:

$container->get('sms.sender');

Mencoba mengakses layanan non-publik langsung dari penampung akan menghasilkan pengecualian.

Layanan bersama dan non-bersama

Secara default, wadah layanan berisi layanan bersama, yang berarti Anda akan menerima instance layanan yang sama di mana pun Anda mengaksesnya di aplikasi. Ini adalah perilaku default wadah layanan Symfony dan berarti Anda tidak perlu menambahkan status apa pun ke layanan Anda. Dalam beberapa kasus tertentu, Anda mungkin ingin mendapatkan instance container yang baru setiap saat. Layanan ini disebut non-shared. Untuk mendeklarasikan non-shared service, cukup tambahkan satu baris ke deklarasi service, seperti yang ditunjukkan di bawah ini:

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        shared: false
        arguments:
            - '@sms.gateway'

Pengkabelan otomatis

Saat mendeklarasikan layanan, Anda dapat menggunakan autowiring argumen. ITU __construct() Metode layanan Anda harus memiliki argumen petunjuk jenis. Kontainer akan mendukung dependensi di __construct() dan secara otomatis meneruskan argumen yang sesuai, seperti yang ditunjukkan di bawah ini:

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        autowire: true

Pengaturan Otomatis

Konfigurasi otomatis adalah fitur yang kuat dari kerangka kerja Symfony yang bekerja mirip dengan autowiring. Namun, alih-alih meneruskan argumen yang benar ke konstruktor, konstruktor secara otomatis menambahkan tag yang diperlukan ke layanan Anda.

Dengan konfigurasi otomatis, Symfony menganalisis layanan Anda dan memeriksa apakah layanan tersebut mengimplementasikan antarmuka yang dikenal oleh container. Jika demikian, penampung akan secara otomatis menambahkan tag yang diperlukan ke layanan.

Dimulai dengan Symfony 6+, konfigurasi otomatis dan pemasangan kabel otomatis diaktifkan secara default untuk semua layanan, menyederhanakan manajemen ketergantungan aplikasi Anda. Dengan memanfaatkan fitur-fitur ini, Anda dapat membuat arsitektur aplikasi yang lebih modular dan dapat dipelihara yang lebih mudah untuk diperluas dan diperbarui.

# services.yml
services:
    sms.sender:
        class: App\Services\SmsService
        autoconfigure: true

Kata kunci

Tag dalam layanan Symfony menyediakan mekanisme yang kuat untuk mengatur dan mengelompokkan layanan terkait. Dengan menandai layanan, Anda dapat dengan mudah mengidentifikasi dan memanipulasinya berdasarkan fungsi atau tujuan umumnya. Tag sangat berguna saat Anda ingin menerapkan operasi atau konfigurasi tertentu ke subkumpulan layanan. Misalnya, jika Anda memiliki beberapa event listener dalam aplikasi, Anda dapat menandainya dengan tag umum seperti “event_listener”. Nanti, Anda dapat mengambil semua layanan dengan tag ini dan melakukan tindakan terhadapnya secara kolektif. Berikut adalah contoh mendefinisikan layanan dengan tag di konfigurasi layanan:

services:
    app.event_listener.sms_was_sent_listener:
        class: App\EventListener\SmsWasSentEventListener
        tags:
            - { name: event_listener, event: my_event }

Dalam contoh ini, app.event_listener.my_listener layanan ditandai dengan event_listener dan dikaitkan dengan peristiwa tersebut my_event. Nanti Anda dapat memulihkan semua layanan dengan event_listener beri tag dan tangani sesuai dengan itu. Dengan memanfaatkan tag, Anda dapat mengonfigurasi dan memanipulasi grup layanan secara dinamis dengan cara yang fleksibel dan dapat diperluas, menjadikan aplikasi Symfony Anda lebih modular dan lebih mudah dipelihara.

Selain tag standar yang disediakan oleh Symfony, Anda juga dapat membuat tag khusus untuk mengkategorikan dan mengidentifikasi layanan Anda lebih lanjut. Tag khusus memungkinkan Anda menentukan kriteria Anda sendiri untuk mengelompokkan layanan dan dapat ditambahkan ke layanan berdasarkan persyaratan atau fungsi tertentu. Ini sangat berguna ketika Anda perlu menerapkan logika atau pemrosesan khusus ke serangkaian layanan tertentu.

Tag khusus memberikan pendekatan yang fleksibel untuk mengkategorikan layanan berdasarkan kebutuhan khusus aplikasi Anda. Mereka memungkinkan Anda untuk mengimplementasikan pemrosesan kustom atau menerapkan fungsionalitas khusus ke grup layanan yang ditargetkan, meningkatkan modularitas dan ekstensibilitas aplikasi Symfony Anda.

Menggunakan Parameter

Kadang-kadang Anda mungkin perlu menggunakan nilai-nilai tertentu dalam layanan Anda yang tidak dapat di-hard-code atau dapat bervariasi tergantung pada lingkungan atau konfigurasi. Dalam kasus seperti itu, Symfony memungkinkan Anda menggunakan parameter dalam deklarasi layanan.

Berikut adalah contoh injeksi ketergantungan Symfony yang menunjukkan cara menggunakan parameter dalam deklarasi layanan:

# services.yml
parameters:
    sms.sender.name: "My SMS Sender"

services:
    sms.sender:
        class: App\Services\SmsService
        arguments:
            - '@sms.gateway'
            - '%sms.sender.name%'

ITU % tanda menunjukkan bahwa parameter harus digunakan. Dalam contoh ini, kami mendefinisikan parameter yang disebut sms.sender.name dengan nilai “Pengirim SMS saya”. Kami kemudian menggunakan parameter ini dalam deklarasi layanan SmsService sebagai argumen kedua.

Symfony Dependency Injection adalah komponen yang sangat kuat dan menyediakan banyak fitur keren yang dapat membantu Anda membangun aplikasi.

Praktik terbaik

Meskipun Injeksi Ketergantungan PHP adalah alat yang ampuh, sangat penting untuk menggunakannya secara efektif dan efisien. Berikut ini beberapa praktik terbaik yang perlu diperhatikan: meminimalkan jumlah dependensi layanan, menghindari dependensi melingkar, menggunakan antarmuka dan petunjuk ketik untuk membuat kode Anda lebih fleksibel, dan menggunakan pemuatan lambat untuk meningkatkan performa .

Symfony menyediakan alat yang kuat dan fleksibel Kerangka kerja injeksi ketergantungan yang dapat dengan mudah menangani kebutuhan proyek Anda.

  • Gunakan antarmuka untuk dependensi: Saat mendefinisikan dependensi, gunakan antarmuka alih-alih kelas konkret. Ini membantu memisahkan kode Anda dan memudahkan untuk beralih implementasi nanti jika diperlukan.
  • Pertahankan wadah kecil: Penting untuk menjaga jumlah layanan dalam wadah seminimal mungkin. Ini membantu mempertahankan kinerja wadah dan membuatnya lebih mudah untuk dikelola. Jika Anda berurusan dengan sejumlah besar layanan, pertimbangkan untuk memecahnya menjadi wadah yang lebih kecil dan lebih fokus.
  • Gunakan injeksi konstruktor alih-alih injeksi setter: Meskipun Symfony mendukung injeksi konstruktor dan setter, umumnya yang terbaik adalah menggunakan injeksi konstruktor jika memungkinkan. Injeksi konstruktor memastikan bahwa semua dependensi tersedia saat objek dibuat, membuatnya lebih mudah untuk memikirkan kode.
  • Gunakan kabel otomatis dengan hati-hati: Meskipun kabel otomatis dapat menjadi cara yang mudah untuk mendeklarasikan layanan dan ketergantungannya, ini juga dapat menyebabkan masalah yang sulit di-debug jika digunakan secara tidak benar. Gunakan kabel otomatis dengan hati-hati dan pastikan untuk menguji kode Anda secara menyeluruh.
  • Hindari ketergantungan melingkar: Ketergantungan melingkar terjadi ketika dua atau lebih layanan bergantung satu sama lain. Ini bisa sulit untuk dikelola dan dapat menyebabkan masalah kinerja. Hindari dependensi melingkar jika memungkinkan dengan memfaktorkan ulang kode Anda atau menggunakan arsitektur berbasis peristiwa.

Kesimpulan

Kesimpulannya, Injeksi Ketergantungan Symfony adalah alat yang ampuh untuk mengelola dependensi kelas secara efektif dengan cara yang terstruktur dan dapat dipelihara. Symfony menawarkan service container yang kuat dan fleksibel, membuat penerapan injeksi ketergantungan menjadi mulus di aplikasi Anda. Dengan menggunakan fitur seperti autowiring, autoconfiguration, dan pengaturan, Anda dapat merampingkan arsitektur aplikasi Anda dan membuatnya lebih modular dan lebih mudah dipelihara.

[ad_2]