Servis Konteynerleri - Laravel

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, UserControllerbir veri kaynağından kullanıcıları almak gerekiyor. Dolayısıyla, kullanıcıları alabilecek bir hizmeti enjekte edeceğiz . Bu bağlamda, bizim UserRepositorybü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ı UserRepositorytest 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->appbindClosure

$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

singletonYö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

instanceYö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 EventPusherarayüze ve bir RedisEventPusheruygulamanıza sahip olduğumuzu varsayalım. Bizim kodlu sonra RedisEventPusherbu arayüzün uygulanmasını, böylece gibi hizmet konteyner ile kaydedebilirsiniz:

$this->app->bind(
    'App\Contracts\EventPusher',
    'App\Services\RedisEventPusher'
);

Bu deyim, RedisEventPusherbir sınıfın bir uygulamanın gerektiğinde enjekte etmesi gerektiğini kapsayıcıya bildirir EventPusher. Şimdi, EventPusherarabirimi 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ı Reportarabirim uygulaması içeren bir dizi alan bir rapor toplayıcı inşa ediyorsunuzdur. Uygulamaları kaydettikten sonra, Reportaş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 taggedyöntemle kolayca çözebilirsiniz :

$this->app->bind('ReportAggregator', function ($app) {
    return new ReportAggregator($app->tagged('reports'));
});

 

Çözülüyor

 

makeYöntem

Sen kullanabilir makekabın dışına sınıf örneğini çözmek için yöntem. makeYö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 $appdeğişkeni, genel kullanabilir resolveyardı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 resolvingyö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

Yorum Yollayın