4

サービスコンテナ/プロバイダーはおそらく私が想像するよりもはるかに単純な概念ですが、数時間の読書の後ではまだ完全には得られません。Laravel - サービスコンテナ/カスタムクラスごとにサービスプロバイダが必要ですか?

DateFormatクラスをapp/Library以内に作成しました。 \config\app.phpのエイリアスを作成した後、すぐにコントローラやブレードテンプレートで使用できます。

<?php namespace App\Library; 

class DateFormat { 

    public static function getDate($timestamp){ 
     // processing the timestamp  
    } 

} 

サービスコンテナを作成しましたか?はいの場合は、サービスプロバイダを作成する必要がありますか?画像に縛られるのはどこですか?

私は本当に被験者に感謝します。
ありがとう

答えて

3

いいえあなたが作成したものは、単にクラスのエイリアスです。サービスプロバイダは特定のクラスをバインドする方法であり、しばしばFacadeと組み合わせて使用​​されます。

エイリアスは、毎回ネームスペースクラス全体をインポートすることなく、クラスを使用する簡単な方法です。例えば

あなたはクラス\My\Very\Long\Class\Adapterを持っている場合、あなたはconfig/app.phpでこれをエイリアスできます

// config/app.php 
<?php 
'aliases' => [ 
    // a bunch of aliases 
    'MyAdapter' => My\Very\Long\Class\Adapter::class, 
] 

そして今、あなただけで行うことができます。

<?php 

new MyAdapter(); 
... 

の代わり:

<?php 

use My\Very\Long\Class\Adapter; 
... 
new Adapter(); 
... 

サービスプロバイダは、依存関係を解決したい場合によく使用されます。mo一般的に注射による。これは、解決したいクラスが、コンストラクタに渡すパラメータを必要とするか、毎回共通の設定をする必要がある場合に役立ちます。そのすべての設定はプロバイダで実行できます。あなたはと対話したいAPIを持っている

は、ここでのシナリオです。我々はそれをSuperApiと呼ぶことにする。 SuperAPIのためのドキュメントはSuperApiクラスのインスタンスを作成するために、あなたが何かしなければならないことを言う:

<?php 
// Some method (a controller or something) 
public function index() 
{ 
    $superApi = new \SuperApi\Connector($key, $secret); 
    return $superApi->getCustomers(); 
} 

を、あなたがこののインスタンスを作成するたびに、あなたは同じことを行う必要があるでしょうセットアップ(またはそれをいくつかのクラスに抽象化しますが、実際には$key$secretをコンストラクタに渡す必要があります)。あなたはこのConnectorクラスのエイリアスを作成した場合

が、多分それは次のようになります。そのエイリアスを持つので

// config/app.php 
<?php 
'aliases' => [ 
    // a bunch of aliases 
    'SuperApi' => SuperApi\Connector::class, 
] 

、あなたは今、これを行うことができます:

<?php 

// Some method (a controller or something) 
public function index() 
{ 
    $superApi = new SuperApi($key, $secret); 
    return $superApi->getCustomers(); 
} 

しかし、あなたが見ます、エイリアスでも、$key$secretを渡す必要があります。

これは、サービスプロバイダが役立つところです。

// app/Providers/SuperApiProvider.php 
<?php 

namespace App\Providers; 

use SuperApi\Connector; 
use Illuminate\Support\ServiceProvider; 

class SuperApiProvider extends ServiceProvider 
{ 
    /** 
    * Register bindings in the container. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->bind('superApiConnector', function ($app) { 
      return new ApiConnector($app['config']->get('super-api.key'), $app['config']->get('super-api.secret')); 
     }); 
    } 
} 

// app/Providers/SuperApi.php (the Facade) 
<?php 

namespace App\Providers; 

use Illuminate\Support\Facades\Facade; 

class SuperApi extends Facade 
{ 
    protected static function getFacadeAccessor() 
    { 
     return 'superApiConnector'; 
    } 
} 


// config/super-api.config 
<?php 

return [ 
    'key' => env('SUPER_API_KEY'), 
    'secret' => env('SUPER_API_SECRET'), 
]; 

// config/app.php 
<?php 
'providers' => [ 
    // a bunch of providers 
    App\Providers\SuperApiProvider::class, 
] 

あなたは、プロバイダにに結合した文字列( 'superApiConnector'が)あなたは正面から戻るとファサードのクラス名は、あなたが実際にこの中には、バインドさクラスと呼ぶことにしますどのようにあるものと同じであることを参照してください。ケース SuperApi。あなたはそれを注入し、 Laravel's IoC Containerを持ちたい時にプロバイダが本当に便利にされています

<?php 

// Some method (a controller or something) 
public function index() 
{ 
    return SuperApi::getCustomers(); 
} 

そして、私は上記の言ったように、:今すぐ

、あなたがSuperApi\Connectorクラスのユーザーにしたいとき、あなたがこれを行うことができます

<?php 
// Some method (a controller or something) 
public function index(SuperApi $api) 
{ 
    return $api->getCustomers(); 
} 

明らかに、依存関係注入を利用するにはサービスプロバイダは必要ありません。アプリケーションでクラスを解決できるのであれば、クラスを注入できます。つまり、あなたが注入しているクラスのコンストラクタが自動的に解決可能である必要があるあらゆる引数を意味します。

+0

ありがとう、これは私が一晩中探していた答えです。さらに2つの質問があります:1. app.phpのプロバイダリストに 'SuperApiProvider'を追加して注入作業をする必要はありませんか? 2.プロバイダでは、理論上、バインディング内部のファサードを、 '$ this-> app-> bind(' App \ SuperApi \ Connector '、function($ app){'? –

+0

最初の質問に置き換えてもかまいません。私はそれを答えに追加しました。あなたの2番目の質問が行く限り、あなたは確かに最初の引数としてクラスパスを渡してファサードを削除します。これを行った場合、フルクラスパスを使用してインポートする必要がありますファサードを使用しない場合は、 'SuperApiConnector :: getCustomers()'を実行することはできません(私の例では)そのメソッドは実際には静的ではありません – tptcat

+0

素敵な精巧な答えをありがとう、すべての部分が配置されました! –

関連する問題