2015-12-22 6 views
7

Laravelフレームワークのコアでシングルトンサービスをオーバーライドする簡単な方法があるのだろうか?Laravelコンテナのシングルトンをオーバーライドする

nameコマンドサービス「」次のプロバイダと::私は、アプリを書き換えしようとしている

use Hexavel\Console\AppNameCommand; 
use Illuminate\Console\Events\ArtisanStarting; 
use Illuminate\Contracts\Events\Dispatcher; 
use Illuminate\Support\ServiceProvider; 

class NameCommandProvider extends ServiceProvider 
{ 
    /** 
    * Register any other events for your application. 
    * 
    * @param \Illuminate\Contracts\Events\Dispatcher $events 
    * @return void 
    */ 
    public function boot(Dispatcher $events) 
    { 
     $events->listen(ArtisanStarting::class, function ($event) { 
      $event->artisan->resolve('command.app.name'); 
     }, -1); 
    } 

    /** 
    * Register the service provider. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->singleton('command.app.name', function ($app) { 
      return new AppNameCommand($app['composer'], $app['files']); 
     }); 
    } 
} 

私はすべてが原因広範囲のチェックに取り組んでいる100%は関係なく、私は(上記の私のサービスプロバイダを入れてどのような順序入れませんよまたはConsoleSupportServiceProviderを下回っている場合)、私のカスタムAppNameCommandを元のAppNameCommandにロードします。

これまでにシングルトンサービスの動作について知っておいた方がいいでしょうか? (これはLaravel 5.2で差があれば使用しています)

答えて

5

私はこのケースを見て、簡単なものではないようです。カスタムプロバイダーでsingletonを使用すると、デフォルトプロバイダー(延期されたプロバイダー)によって最終的にオーバーライドされるので、それは方法ではないようです。

単純なアプローチが機能しないことを確認した後、このような場合に必要なことは、Laravelがこのコマンドを登録したときに何が起きているのかを分析することです。

あなたのケースでは、最初にcommand.app.nameを検索します - それはIlluminate\Foundation\Providers\ArtisanServiceProviderにあり、方法registerAppNameCommandがあると思われます。

は、だから今、あなたはそれが起動だ場所を確認するためにArtisanServiceProviderの出現箇所を探して - あなたはそれが(あなたが変更したいと思いますおそらく)$providersプロパティにIlluminate\Foundation\Providers\ConsoleSupportServiceProviderにあります参照してください。

最後に、ConsoleSupportServiceProviderの出現を探して、それがconfig/app.phpにあることを確認する必要があります。

ですから、この場合には何をする必要があるか:config/app.php

  • 変更 - あなたは\Illuminate\Foundation\Providers\ConsoleSupportServiceProviderから拡張する必要がありますカスタム一つのカスタムに変更
  • しかしIlluminate\Foundation\Providers\ArtisanServiceProviderから$providersの変化にあなたのカスタムArtisanServiceProvider
  • 最終的にカスタムArtisanServiceProviderを作成します。これは\Illuminate\Foundation\Providers\ArtisanServiceProviderから拡張されます。ここでは、カスタムclを使用してregisterAppNameCommandを上書きします。この方法を使用してsingleton

でお尻あなたは(私はカスタムクラスは、コマンドphp artisan app:nameを実行している使用されることを確認した)あなたの目標を達成します。

ArtisanServiceProvider$devCommandsから削除し、シングルトンを登録した場所を示すようにカスタムサービスプロバイダを使用することもできますが、この方法は試していません。

+0

はい私はこれがオーバーライドとそれを行う唯一の方法として動作すると思ったが正直言ってそれは残念です非常にclunkyオプションです。私はまた、新しいコマンドがapp:nameを置き換えるなどして解決することでコマンドをオーバーライドすることもできます。他の人がcommand.app.nameサービスが冗長であることを知らなければ潜在的な問題につながる可能性があります –

+1

そうです、そうですLaravelのいくつかの機能は、それらを動作させるために多くの変更を加える必要がありますが、他のフレームワークではそれはさらに悪いことです:) –

7

これを行うには実際にはよりクリーンな方法があります。

$this->app->extend('command.app.name', function ($command, $app) { 
    return new AppNameCommand($app['composer'], $app['files']); 
}); 

Jason LewisTutsplusにLaravelのIoCについては本当に素晴らしい記事を持っている:あなたは基本的にextend方法を用いることによって達成することができる結合コアを拡張します。それをチェックすることを確認してください;)

関連する問題