簡體   English   中英

Laravel服務提供商解釋

[英]Laravel service provider explanation

我對Laravel服務提供商並不熟悉,我對此有疑問。

示例:我有三個類SystemProfiler,SurveyProfiler和OfferProfiler,它們實現了ProfilerInterface。 我還有ProfilerService類,它在構造函數中注入了ProfilerInterface。 我需要創建不同的ProfilerService服務,並注入每個分析器。

ProfilerService:

class ProfilerService {

    $this->profiler;

    function __construct(ProfilerInterface $profiler) {
            $this->profiler = profiler;
    }
}

我知道如何在symfony2框架中這樣做:

system_profiler:
    class: App\MyBundle\Profiles\SystemProfiler

survey_profiler:
    class: App\MyBundle\Profiles\SurveyProfiler

offer_profiler:
    class: App\MyBundle\Profiles\OfferProfiler

system_profile_service:
    class: App\MyBundle\Services\ProfilerService
    arguments:
        - system_profiler

survey_profile_service:
    class: App\MyBundle\Services\ProfilerService
    arguments:
        - survey_profiler

offer_profile_service:
    class: App\MyBundle\Services\ProfilerService
    arguments:
        - offer_profiler

然后使用ProfilerService實現的別名調用$this->container->get()

但是Laravel文檔說“ 如果不依賴於任何接口,就不需要將類綁定到容器中 ”。 而ProfilerService不依賴於接口。 所以我可以將每個探查器綁定到接口,如下所示:

   $this->app->bind('App\MyBundle\Contracts\ProfilerInterface','App\MyBundle\Profiles\SystemProfiler');

要么

$this->app->bind('App\MyBundle\Contracts\ProfilerInterface','App\MyBundle\Profiles\SurveyProfiler');

要么

$this->app->bind('App\MyBundle\Contracts\ProfilerInterface','App\MyBundle\Profiles\OfferProfiler');

但是我應該如何綁定哪些Profilers應該注入到ProfilerService中?

我將不勝感激任何幫助和解釋

ProfilerService的構造函數鍵入一個接口,這意味着您的ProfilerService確實依賴於接口。

沒有任何額外的設置,如果您嘗試App::make('App\\MyBundle\\Services\\ProfilerService'); ,你會得到一個錯誤,因為Laravel不知道如何解決接口依賴。

然后當你執行$this->app->bind('App\\MyBundle\\Contracts\\ProfilerInterface','App\\MyBundle\\Profiles\\SystemProfiler'); 在您的服務提供商中,您告訴Laravel“無論何時您需要解析ProfilerInterface,創建一個新的SystemProfiler”。

使用該綁定設置,如果您然后嘗試App::make('App\\MyBundle\\Services\\ProfilerService'); ,Laravel將創建一個新的ProfilerService實例,並在構造函數中注入一個新的SystemProfiler實例。

但是,這並不是您想要的,因為您有三種不同的ProfilerInterface實現。 你不希望Laravel總是只注射一個。 在這種情況下,您將創建自定義綁定,類似於您在Symfony中所做的操作。

在您的服務提供中,您的綁定看起來像這樣:

$this->app->bind('system_profile_service', function($app) {
    return $app->make('App\MyBundle\Services\ProfilerService', [$app->make('App\MyBundle\Profiles\SystemProfiler')]);
});

$this->app->bind('survey_profile_service', function($app) {
    return $app->make('App\MyBundle\Services\ProfilerService', [$app->make('App\MyBundle\Profiles\SurveyProfiler')]);
});

$this->app->bind('offer_profile_service', function($app) {
    return $app->make('App\MyBundle\Services\ProfilerService', [$app->make('App\MyBundle\Profiles\OfferProfiler')]);
});

現在,通過這些綁定設置,您可以在需要時從IOC解析自定義綁定。

$systemProfiler = App::make('system_profiler_service');
$surveyProfiler = App::make('survey_profile_service');
$offerProfiler = App::make('offer_profile_service');

在這里( 閱讀文檔 ):

// ServiceProvider
public function register()
{
    // Simple binding
    $this->app->bind('some_service.one', \App\ImplOne::class);
    $this->app->bind('some_service.two', \App\ImplTwo::class);

    // Aliasing interface - container will inject some_service.one
    // whenever interface is required...
    $this->app->alias('some_service.one', \App\SomeInterface::class);

    // ...except for the Contextual Binding:
    $this->app->when(\App\DependantTwo::class)
              ->needs(\App\SomeInterface::class)
              ->give('some_service.two');
}

用法:

$ php artisan tinker

// Aliases
>>> app('some_service.one')
=> App\ImplOne {#669}
>>> app('some_service.two')
=> App\ImplTwo {#671}

// Aliased interface
>>> app('App\SomeInterface')
=> App\ImplOne {#677}
>>> app('App\DependantOne')->dependency
=> App\ImplOne {#677}

// Contextual
>>> app('App\DependantTwo')->dependency
=> App\ImplOne {#676}

鑒於此設置:

namespace App;

class ImplOne implements SomeInterface {}

class ImplTwo implements SomeInterface {}

class DependantOne
{
    public function __construct(SomeInterface $dependency)
    {
        $this->dependency = $dependency;
    }
}

class DependantTwo
{
    public function __construct(SomeInterface $dependency)
    {
        $this->dependency = $dependency;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM