1

我在让 Facade 与注入底层类的依赖项一起正常工作时遇到问题。

我有一个名为“Listing”的课程。它有一个名为“AdvertRepository”的依赖项,它是一个接口和一个名为 EloquentAdvert 的类,它实现了该接口。这三个类的代码在这里:

// 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 并显示“this has working”。

// 控制器/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();
    }
}

现在,我为列表创建了一个外观。我添加了一个新的外观如下,并在 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 工作正常。

似乎当通过其外观访问列表时,AdvertRepository 和 EloquentAdvert 之间的绑定不起作用。我在 ServiceProvider 中查看了我的代码,认为这是问题所在,但我无法弄清楚。

Facade 和绑定在单独测试时都有效,但在同时使用时则无效。

有任何想法吗???

4

2 回答 2

3

好的,所以我想通了...对于那些遇到类似问题的人...

有问题的语句在 ListingServiceProvider.php 中,内容如下:

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

The error is the new AdvertRepository statement. The reason being is that, we are telling php to directly instantiate the interface 'AdvertRepository'. Instead, we need to tell Laravel to instantiate the appropriate implementation of the 'AdvertRepository' interface. To do that, we use App::make('AdvertRepository'). That way, Laravel uses the binding previously declared to instantiate the correct implementation.

于 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 回答