Rumah >pembangunan bahagian belakang >tutorial php >Suntikan ketergantungan dengan Laravel ' s IOC
Takeaways Key
Suntikan ketergantungan adalah elemen utama seni bina tangkas.
mari kita lihat contoh:
Jika anda ingin menguji atau mengekalkan kelas ini, anda perlu mengakses pangkalan data sebenar dan melakukan beberapa pertanyaan. Untuk mengelakkan daripada melakukan itu dan untuk
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>$this->connection = new Connection; </span> <span>} </span> <span>public function retrieveByCredentials( array $credentials ){ </span> <span>$user = $this->connection </span> <span>->where( 'email', $credentials['email']) </span> <span>->where( 'password', $credentials['password']) </span> <span>->first(); </span> <span>return $user; </span> <span>} </span><span>}</span>decouple
kelas dari yang lain, anda mempunyai satu daripada tiga pilihan untuk menyuntik kelas sambungan tanpa menggunakannya secara langsung. Apabila menyuntik komponen ke dalam kelas anda, anda boleh menggunakan salah satu daripada tiga pilihan:
Suntikan Pembina
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>
Suntikan antara muka
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>... </span> <span>} </span> <span>public function setConnection( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>
<span>interface ConnectionInjector{ </span> <span>public function injectConnection( Connection $con ); </span><span>} </span> <span>class UserProvider implements ConnectionInjector{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>... </span> <span>} </span> <span>public function injectConnection( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span><span>}</span>
Sekarang, ketika menguji kelas kita, kita dapat mengejek kelas pergantungan dan lulus sebagai parameter. Setiap kelas mesti difokuskan pada tugas tertentu dan tidak perlu bimbang dengan menyelesaikan kebergantungan mereka. Dengan cara itu, anda akan mempunyai aplikasi yang lebih fokus dan boleh dipelihara.
Jika anda ingin mengetahui lebih lanjut mengenai DI, Alejandro Gervassio meliputi secara meluas dan profesional dalam siri ini, jadi pastikan anda memberi artikel -artikel ini dibaca. Sekarang, bagaimana dengan IOC? IOC (penyongsangan kawalan) tidak perlu menggunakan suntikan ketergantungan, tetapi ia dapat membantu anda menguruskan kebergantungan anda dengan berkesan.
IOC adalah komponen mudah yang menjadikan kebergantungan menyelesaikan lebih mudah. Anda menerangkan objek anda ke bekas, dan setiap kali anda menyelesaikan kelas, kebergantungan disuntik secara automatik.
Laravel IOC entah bagaimana istimewa dengan cara menyelesaikan dependensi, apabila anda meminta objek:
Kelas Simpleauth mempunyai kebergantungan FileSessionStorage, jadi kod kami mungkin kelihatan seperti ini:
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>$this->connection = new Connection; </span> <span>} </span> <span>public function retrieveByCredentials( array $credentials ){ </span> <span>$user = $this->connection </span> <span>->where( 'email', $credentials['email']) </span> <span>->where( 'password', $credentials['password']) </span> <span>->first(); </span> <span>return $user; </span> <span>} </span><span>}</span>Ini adalah cara klasik untuk melakukannya, mari kita mulakan dengan menggunakan suntikan pembina.
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>Sekarang kita buat objek kita:
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>... </span> <span>} </span> <span>public function setConnection( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>sekarang saya mahu menggunakan Laravel IOC untuk menguruskan semua itu.
Kerana kelas aplikasi memanjangkan kelas kontena, anda sentiasa boleh mengakses bekas melalui fasad aplikasi.
<span>interface ConnectionInjector{ </span> <span>public function injectConnection( Connection $con ); </span><span>} </span> <span>class UserProvider implements ConnectionInjector{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>... </span> <span>} </span> <span>public function injectConnection( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span><span>}</span>parameter pertama untuk kaedah pengikat adalah ID unik untuk mengikat pada bekas, yang kedua adalah fungsi panggil balik yang akan dilaksanakan setiap kali kita menyelesaikan kelas FileSessionStorage, kita juga boleh lulus rentetan yang mewakili nama kelas seperti yang kita akan lihat Seterusnya.
Nota: Jika anda memeriksa pakej Laravel, anda akan mengikat kadang -kadang dikumpulkan seperti (Lihat, Lihat.Finder ..).
katakan bahawa mungkin kita mahu menukar storan sesi kami ke MySQL, kelas kami harus sama dengan:
<span>class FileSessionStorage{ </span> <span>public function __construct(){ </span> <span>session_start(); </span> <span>} </span> <span>public function get( $key ){ </span> <span>return $_SESSION[$key]; </span> <span>} </span> <span>public function set( $key, $value ){ </span> <span>$_SESSION[$key] = $value; </span> <span>} </span><span>} </span> <span>class SimpleAuth{ </span> <span>protected $session; </span> <span>public function __construct(){ </span> <span>$this->session = new FileSessionStorage; </span> <span>} </span><span>} </span> <span>//creating a SimpleAuth </span><span>$auth = new SimpleAuth();</span>Sekarang kita telah mengubah ketergantungan, kita perlu menukar pembina Simpleauth dan mengikat objek baru ke bekas!
Modul tahap tinggi tidak boleh bergantung kepada modul tahap rendah. Kedua -duaharus bergantung kepada abstraksi.
Abstraksi tidak boleh bergantung kepada butiran. Butiran harus bergantung
apabila abstraksi.
Robert C. MartinKelas Simpleauth kami tidak perlu prihatin tentang bagaimana storan kami dilakukan, sebaliknya ia harus memberi tumpuan lebih kepada hanya memakan perkhidmatan.
jadi kita boleh abstrak pelaksanaan penyimpanan kita:
Dengan cara ini kita hanya dapat melaksanakan dan meminta contoh antara muka sessionStorage:
<span>class SimpleAuth{ </span> <span>protected $session; </span> <span>public function __construct( FileSessionStorage $session ){ </span> <span>$this->session = $session; </span> <span>} </span><span>}</span>
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>$this->connection = new Connection; </span> <span>} </span> <span>public function retrieveByCredentials( array $credentials ){ </span> <span>$user = $this->connection </span> <span>->where( 'email', $credentials['email']) </span> <span>->where( 'password', $credentials['password']) </span> <span>->first(); </span> <span>return $user; </span> <span>} </span><span>}</span>
Jika kita cuba menyelesaikan kelas Simpleauth melalui bekas menggunakan App :: Make ('Simpleauth'), bekas akan membuang BindingResolutionException, setelah cuba menyelesaikan kelas dari pengikatan, kembali ke kaedah refleksi dan menyelesaikannya semua kebergantungan.
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>Bekas cuba untuk memberi instantiasi antara muka. Kita boleh membetulkannya dengan membuat pengikatan khusus untuk antara muka kita.
<span>class UserProvider{ </span> <span>protected $connection; </span> <span>public function __construct(){ </span> <span>... </span> <span>} </span> <span>public function setConnection( Connection $con ){ </span> <span>$this->connection = $con; </span> <span>} </span> <span>...</span>Sekarang setiap kali kita cuba menyelesaikan antara muka melalui bekas, kita akan mendapat contoh MySqlSessionStorage. Sekiranya kami mahu menukar perkhidmatan storan kami, kami hanya dapat mengemas kini pengikatan.
Nota: Jika anda ingin melihat sama ada kelas terikat pada bekas, anda boleh menggunakan apl :: terikat ('classname') atau gunakan apl :: bindif ('classname') untuk mendaftarkan pengikatan jika ia tidak mempunyai ' t sudah didaftarkan.
Laravel IOC juga menawarkan App :: Singleton ('ClassName', 'Resolver') untuk pengikatan bersama.
Anda juga boleh menggunakan App :: Instance ('ClassName', 'Instance') untuk membuat contoh bersama.
Sekiranya bekas tidak dapat menyelesaikan kebergantungan, ia akan membuang refleksiException, tetapi kita boleh menggunakan aplikasinya :: resolvingyAny (penutupan) untuk menyelesaikan sebarang jenis yang diberikan atau sebagai bentuk sandaran.
Petua Akhir
Apakah tujuan utama suntikan ketergantungan dalam IOC Laravel? Ini bermakna bahawa bukannya mempunyai objek anda yang mewujudkan kebergantungan atau meminta objek kilang untuk membuatnya untuk mereka, anda lulus kebergantungan yang diperlukan ke dalam objek secara luaran. Ini menjadikan kod anda lebih fleksibel, boleh diguna semula, dan lebih mudah untuk diuji kerana anda dapat mengawal kebergantungan dari luar kelas.
Atas ialah kandungan terperinci Suntikan ketergantungan dengan Laravel ' s IOC. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!