Servis Konteynerleri - Laravel
Servis Konteynerleri
Giriş
Laravel hizmet konteyneri sınıf bağımlılıklarını yönetmek ve bağımlılık püskürtmeyi gerçekleştirmek için güçlü bir araçtır. Bağımlılık enjeksiyonu, aslında şu anlama gelmektedir: sınıf bağımlılıkları kurucuya veya bazı durumlarda "belirleyici" yöntemlerle sınıfa "püskürtülür".
Basit bir örneğe göz atalım:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Repositories\UserRepository;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* The user repository implementation.
*
* @var UserRepository
*/
protected $users;
/**
* Create a new controller instance.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function show($id)
{
$user = $this->users->find($id);
return view('user.profile', ['user' => $user]);
}
}
Bu örnekte, UserController
bir veri kaynağından kullanıcıları almak gerekiyor. Dolayısıyla, kullanıcıları alabilecek bir hizmeti enjekte edeceğiz . Bu bağlamda, bizim UserRepository
büyük olasılıkla kullanan anlamlı veritabanından kullanıcı bilgilerini almak için. Bununla birlikte, depo enjekte edildiğinden, bunu başka bir uygulama ile kolayca değiştirebiliyoruz. Ayrıca, uygulamanızı UserRepository
test ederken "taklit" yapabilir veya kukla bir uygulama oluşturabiliriz.
Laravel hizmet kabının derin bir anlayışı, Laravel çekirdeğinin kendisine katkıda bulunmanın yanı sıra güçlü ve büyük bir uygulama oluşturmak için de gereklidir.
Bağlama
Bağlama Temelleri
Servis konteyner bağlamalarınızın neredeyse tamamı servis sağlayıcılara kaydedilecektir , bu nedenle bu örneklerin çoğu konteynırın bu bağlamda gösterilmesini sağlayacaktır.
Herhangi bir arayüze bağımlı değillerse sınıfları kapsayıcıya bağlamaya gerek yoktur. Konteyner, bu nesneleri yansıtma kullanarak otomatik olarak çözümleyebildiğinden, bu nesnelerin nasıl oluşturulacağı konusunda talimat verilmesine gerek yoktur.
Basit Bağlar
Bir servis sağlayıcıda, mülkten konteynere her zaman erişebilirsiniz . Biz kullanarak bağlama kayıt olabilirsiniz , yöntem bir birlikte kayıt yaptırmak isteyen sınıf veya arabirim adını geçirmeden sınıfının bir örneğini döndürür:$this->app
bind
Closure
$this->app->bind('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
Kabın kendisini çözümleyiciye bir argüman olarak aldığımızı unutmayın. Ardından, oluşturduğumuz nesnenin alt bağımlılıklarını çözmek için kabı kullanabiliriz.
Bağımlı Bir Singleton
singleton
Yöntem, yalnızca bir kez çözülmesi gerektiğini kap içine bir sınıf veya ara yüz bağlanır. Tek bağlama çözüldükten sonra, sonraki nesne örneği konteynerdeki sonraki çağrılarda döndürülür:
$this->app->singleton('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
Bağlama Örnekleri
instance
Yöntem kullanarak mevcut bir nesne örneğini kapsayıcıya da bağlayabilirsiniz . Verilen örnek, konteynerdeki sonraki çağrılarda daima geri gönderilecektir:
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\Api', $api);
Bağlayıcı İlkeller
Bazen bazı enjekte edilen sınıfları alan bir sınıfınız olabilir, ancak aynı zamanda bir tamsayı gibi enjekte edilen ilkel bir değere ihtiyaç duyarsınız. Sınıfınızın ihtiyaç duyduğu herhangi bir değeri enjekte etmek için içeriğe dayalı bağlamayı kolayca kullanabilirsiniz:
$this->app->when('App\Http\Controllers\UserController')
->needs('$variableName')
->give($value);
Uygulamalara Bağlayıcı Arayüzler
Hizmet kabının çok güçlü bir özelliği, bir arabirimi belirli bir uygulamaya bağlama yeteneğidir. Örneğin, bir EventPusher
arayüze ve bir RedisEventPusher
uygulamanıza sahip olduğumuzu varsayalım. Bizim kodlu sonra RedisEventPusher
bu arayüzün uygulanmasını, böylece gibi hizmet konteyner ile kaydedebilirsiniz:
$this->app->bind(
'App\Contracts\EventPusher',
'App\Services\RedisEventPusher'
);
Bu deyim, RedisEventPusher
bir sınıfın bir uygulamanın gerektiğinde enjekte etmesi gerektiğini kapsayıcıya bildirir EventPusher
. Şimdi, EventPusher
arabirimi bir yapıcıda veya bağımlılıkların hizmet kapsayıcısı tarafından enjekte edildiği herhangi bir yerde yazabileceğini ipucu verebiliriz:
use App\Contracts\EventPusher;
/**
* Create a new class instance.
*
* @param EventPusher $pusher
* @return void
*/
public function __construct(EventPusher $pusher)
{
$this->pusher = $pusher;
}
Bağlamsal Bağlama
Bazen aynı arabirimi kullanan iki sınıfınız olabilir, ancak her sınıfın içine farklı uygulamalar enjekte etmek istiyorsunuz. Örneğin, iki kontrol farklı uygulamaları bağlı olabilir sözleşme . Laravel, bu davranışı tanımlamak için basit ve akıcı bir arayüz sağlar:Illuminate\Contracts\Filesystem\Filesystem
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;
$this->app->when(PhotoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('local');
});
$this->app->when(VideoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('s3');
});
Etiketleme
Bazen belirli bir "bağlama" kategorisinin tümünü çözmeniz gerekebilir. Örneğin, pek çok farklı Report
arabirim uygulaması içeren bir dizi alan bir rapor toplayıcı inşa ediyorsunuzdur. Uygulamaları kaydettikten sonra, Report
aşağıdaki yöntemi kullanarak bir etiket atayabilirsiniz tag
:
$this->app->bind('SpeedReport', function () {
//
});
$this->app->bind('MemoryReport', function () {
//
});
$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');
Hizmetler etiketlendiğinde bunları aşağıdaki tagged
yöntemle kolayca çözebilirsiniz :
$this->app->bind('ReportAggregator', function ($app) {
return new ReportAggregator($app->tagged('reports'));
});
Çözülüyor
make
Yöntem
Sen kullanabilir make
kabın dışına sınıf örneğini çözmek için yöntem. make
Yöntem gidermek isteyen sınıf veya arabirimin adını kabul eder:
$api = $this->app->make('HelpSpot\API');
Eğer erişimi yok Kodunuzun konumda iseniz $app
değişkeni, genel kullanabilir resolve
yardımcı:
$api = resolve('HelpSpot\API');
Otomatik Enjeksiyon
Alternatif olarak ve önemlisi, denetleyici , olay dinleyicisi , sıra işi , ara katman ve daha fazlası gibi kapsayıcı tarafından çözümlenen bir sınıfın yapıcısına bağımlılığı basitçe "yazın-ipucu" verebilirsiniz . Pratikte, nesnelerinizin çoğunun konteyner tarafından çözülmesi gerektiği budur.
Örneğin, bir denetleyicinin yapıcısında uygulamanız tarafından tanımlanan bir depoyu yazın yazabilirsiniz. Depo otomatik olarak çözülecek ve sınıfa enjekte edilecektir:
<?php
namespace App\Http\Controllers;
use App\Users\Repository as UserRepository;
class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users;
/**
* Create a new controller instance.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
/**
* Show the user with the given ID.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
}
Konteyner Etkinlikleri
Servis kabı, bir nesneyi her çözdüğünde bir olay tetikliyor. Aşağıdaki resolving
yöntemi kullanarak bu etkinliği dinleyebilirsiniz:
$this->app->resolving(function ($object, $app) {
// Called when container resolves object of any type...
});
$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
// Called when container resolves objects of type "HelpSpot\API"...
});
Gördüğünüz gibi, çözülmekte olan nesne, geri bildirime geçirilecek ve nesneye tüketici tarafından verilmeden önce ek özellikler ayarlamanıza izin verilecek.
Henüz Yorum Yapılmamış, İlk Yorumu Siz Yapın