1

基礎となるクラスに注入された依存関係を使用して Facade を適切に機能させる際に問題が発生しています。

「Listing」というクラスがあります。インターフェースである「AdvertRepository」と呼ばれる1つの依存関係と、インターフェースを実装するEloquentAdvertと呼ばれるクラスがあります。これら 3 つのクラスのコードは次のとおりです。

// PlaneSaleing\Providers\Listing.php

<?php namespace PlaneSaleing\Providers;

use PlaneSaleing\Repositories\Advert\AdvertRepository;

class Listing {

    protected $advert;

    public function __construct (AdvertRepository $advert_repository) {
        $this->advert = $advert_repository;
    }

    public function test() {
            $this->advert->test();
    }

    public function test2() {
        echo "this has worked";
    }
}

// PlaneSaleing\Repositories\Advert\AdvertRepository.php

<?php namespace PlaneSaleing\Repositories\Advert;

interface AdvertRepository {

    public function test();

}

// PlaneSaleing\Repositories\Advert\EloquentAdvert.php;

<?php namespace PlaneSaleing\Repositories\Advert;

class EloquentAdvert implements AdvertRepository {

    public function test() {
        echo 'this has worked';
    }
}

次に、次のコードを持つ ListingServiceProvider.php というサービス プロバイダーを作成しました。

// PlaneSaleing/Providers/ListingServiceProvider.php

<?php  namespace PlaneSaleing\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\App;

class ListingServiceProvider extends ServiceProvider {

    public function register() {

        App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', 'PlaneSaleing\Repositories\Advert\EloquentAdvert');

    }
}

これを app.php の ServiceProviders 配列にも追加しました

ここで、Listing を依存関係としてコントローラーに注入し、テスト メソッドを呼び出すと (以下に示すように)、Laravel は依存関係を正しく検出し、バインディングを介して EloquentAdvert をインスタンス化し、「これは機能しました」と表示します。

// コントローラ/TestController.php

use PlaneSaleing\Providers\Listing;

class TestController extends BaseController {

    protected $listing;

    public function __construct(Listing $listing) {
        $this->listing = $listing;
    }

    public function test1() {
        $this->listing->test();
    }
}

次に、Listing のファサードを作成しました。次のように新しいファサードを追加し、app.php にエイリアスを追加しました。

// PlaneSaleing\Providers\ListingFacade.php

<?php  namespace PlaneSaleing\Providers;

use Illuminate\Support\Facades\Facade;

class ListingFacade extends Facade {

    protected static function getFacadeAccessor() {

        return 'Listing';
    }
}

また、次の新しい行を ListingServiceProvider.php に追加しました。

<?php  namespace PlaneSaleing\Providers;

use PlaneSaleing\Repositories\Advert\AdvertRepository;
use PlaneSaleing\Repositories\Advert\EloquentAdvert;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\App;

class ListingServiceProvider extends ServiceProvider {

    public function register() {

        App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', 'PlaneSaleing\Repositories\Advert\EloquentAdvert');

        // New lines...
        $this->app['Listing'] = $this->app->share(function() {
            return new Listing(new AdvertRepository);
        });
    }
}

今... Listing::test() を呼び出すと、次のエラーが発生しますCannot instantiate interface PlaneSaleing\Repositories\Advert\AdvertRepository

Listing::test2() を呼び出すと、「これは機能しました」と表示されるため、Facade が正しく機能しているように見えます。

Facade を介して Listing にアクセスすると、AdvertRepository と EloquentAdvert の間のバインディングが機能しないようです。問題だと思って ServiceProvider のコードを調べましたが、わかりません。

Facade とバインディングは、個別にテストすると機能しますが、両方を同時に使用すると機能しません。

何か案は???

4

2 に答える 2

3

OK、だから私はそれを理解しました...同様の問題に遭遇した人のために...

問題のあるステートメントは ListingServiceProvider.php にあり、次のように書かれていました。

$this->app['Listing'] = $this->app->share(function() {
    return new Listing(new AdvertRepository);
});

エラーはnew AdvertRepositoryステートメントです。その理由は、インターフェイス「AdvertRepository」を直接インスタンス化するように php に指示しているためです。代わりに、「AdvertRepository」インターフェースの適切な実装をインスタンス化するよう Laravel に指示する必要があります。そのために、 を使用しますApp::make('AdvertRepository')。そうすれば、Laravel は以前に宣言されたバインディングを使用して正しい実装をインスタンス化します。

于 2013-09-23T15:48:36.380 に答える
0

コンストラクターにクラスが注入されていない場合、特定のインターフェースをインスタンス化する必要があるときにどのクラスを使用するかを Laravel に伝える必要があります。

これをフィルターまたはバインディング ファイルに入れます。

App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', function()
{
    return new PlaneSaleing\Repositories\Advert\EloquentAdvert;
});
于 2013-09-21T17:40:06.850 に答える