Apakah itu Service Container
Laravel service Container ialah alat yang berkuasa untuk menguruskan kebergantungan kelas dan melaksanakan suntikan kebergantungan.
Daripada penjelasan Kontena Perkhidmatan dalam dokumentasi rasmi Laravel, kami dapat melihat bahawa peranannya adalah untuk membantu kami mengurus dan melaksanakan suntikan tanggungan.
Mengapa menggunakan Service Container
Dalam "Dependency Injection", kami melihat bahawa menggunakan dependency injection boleh mengurangkan gandingan kod, tetapi ia juga membawa kelemahan, iaitu ia memerlukan Manage objek yang disuntik sendiri.
Jika komponen mempunyai banyak kebergantungan, kita perlu mencipta kaedah penetap dengan berbilang parameter untuk melepasi kebergantungan, atau mencipta pembina dengan berbilang parameter untuk melepasinya. Selain itu, kita perlu mencipta kebergantungan setiap kali sebelum menggunakan komponen . Ini menjadikan kod kami seperti ini kurang boleh diselenggara.
Jadi menyediakan bekas (Bekas Perkhidmatan) untuk contoh bergantung adalah kaedah yang praktikal dan elegan.
Sebagai contoh, berikut ialah fail masukan laravel (komen telah dialih keluar):
// public/index.php <?php require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);
// bootstrap/app.php <?php $app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); $app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); return $app;
Pertama lihat bootstrap/app.php
, dengan $app
ialah contoh IlluminateFoundationApplication
, dan IlluminateFoundationApplication
Kelas mewarisi daripada Bekas, jadi $app
sebenarnya ialah Bekas Perkhidmatan.
Kemudian tiga kaedah tunggal berikut menentukan kelas mana untuk menyuntik tunggal apabila bergantung pada tiga antara muka IlluminateContractsHttpKernel
, IlluminateContractsConsoleKernel
dan IlluminateContractsDebugExceptionHandler
.
Kemudian lihat public/index.php
Kaedah buat sebenarnya menggunakan Bekas Perkhidmatan untuk mencipta contoh IlluminateContractsHttpKernel
baharu.
Bukankah ia sangat mudah?
Malah, bukan sahaja Laravel, tetapi juga rangka kerja seperti Yii2 dan Phalcon menguruskan suntikan pergantungan dengan melaksanakan bekas.
Cara menggunakan Bekas Perkhidmatan
Memandangkan ia adalah bekas, ia tidak lebih daripada dua perkara, memasukkan dan mengeluarkan barang yang sepadan dengan Bekas Perkhidmatan adalah mengikat dan menyelesaikannya. .
Dapatkan bekas itu
Dalam Pembekal Perkhidmatan Laravel, anda boleh mendapatkan bekas melalui $this->app
Selain itu, anda juga boleh menggunakan app()
untuk mendapatkan bekas.
Jika anda menggunakan Bekas Perkhidmatan di luar Laravel, buat sahaja bekas baharu IlluminateContainerContainer
untuk mendapatkan bekas itu.
$container digunakan di bawah untuk mewakili bekas yang diperoleh.
Mengikat
Mengikat mengembalikan contoh antara muka
//使用闭包 $container->bind('BarInterface', function(){ return new Bar(); }); //或者使用字符串 $container->bind('FooInterface', 'Foo');
Mengikat tunggal Untuk contoh,
kaedah tunggal mengikat kelas atau antara muka yang hanya akan dihuraikan sekali ke bekas dan panggilan seterusnya akan mengembalikan contoh yang sama daripada bekas:
$container->singleton('BarInterface', function(){ return new Bar(); });
Ikat tika
Anda juga boleh menggunakan kaedah contoh untuk mengikat tika objek sedia ada ke tengah bekas. Panggilan seterusnya akan mengembalikan contoh yang dinyatakan daripada bekas:
$bar = new Bar(); $bar->setSomething(new Something); $container->instance('Bar', $bar);
Pengikatan konteks
Kadangkala, anda boleh mempunyai dua kelas yang menggunakan antara muka yang sama, tetapi anda mahu setiap kelas dapat menyuntik pelaksanaan yang berbeza.
$container->when('Man') ->needs('PartnerInterface') ->give('Woman'); $container->when('Woman') ->needs('PartnerInterface') ->give('Man');
Tandakan
Kadangkala, anda mungkin perlu menghuraikan semua pengikatan di bawah "kategori" tertentu .
$container->bind('Father', function () { // }); $container->bind('Mother', function () { // }); $container->bind('Daughter', function () { // }); $container->bind('Son', function () { // }); $container->tag(['Father', 'Mother', 'Daughter', 'Son'], 'familyMembers'); $container->bind('Family', function ($container) { return new Family($container->tagged('familyMembers')); });
Menghuraikan
membuat kaedah
$foo = $container->make('Foo');
kaedah tatasusunan
$bar = $container['Bar'];
Penghuraian ditanda dan diikat
$familyMembers = $container->tagged('familyMembers'); foreach ($familyMembers as $inpidual) { $inpidual->doSomething(); }
Acara penghuraian
Acara dicetuskan apabila bekas perkhidmatan menyelesaikan objek. Anda boleh mendengar acara ini menggunakan kaedah penyelesaian.
$container->resolving(function ($object, $container) { // 当容器解析任何类型的对象时会被调用... }); $container->resolving('Foo', function (Foo $foo, $container) { // 当容器解析「Foo」类型的对象时会被调用... });
Cadangan berkaitan: Lima tutorial video Laravel terbaharu