Laravel 4 中的外观和注入依赖项的问题


Issue with Facade and injected dependency in Laravel 4

我在使外观正常工作时遇到问题,并将依赖项注入到底层类中。

我有一个名为"列表"的课程。它有一个名为"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''Repository''Advert''AdvertRepository.php

<?php namespace PlaneSaleing'Repositories'Advert;
interface AdvertRepository {
    public function test();
}

PlaneSaleing''Repository''Advert''EloquentAdvert.php;

<?php namespace PlaneSaleing'Repositories'Advert;
class EloquentAdvert implements AdvertRepository {
    public function test() {
        echo 'this has worked';
    }
}

然后,我创建了一个名为 ListingServiceProvider.php 的服务提供程序,它具有以下代码:

飞机销售/提供商/列表服务提供商.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');
    }
}

我还将其添加到应用程序中的服务提供者数组中.php

现在,如果我将 Listing 作为依赖项注入控制器并调用测试方法(如下所示),Laravel会正确检测依赖项,通过其绑定实例化 EloquentAdvert 并显示"这已经奏效"。

控制器/测试控制器.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() ,我会得到"这已经起作用",所以看起来外观工作正常。

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

立面和装订在单独测试时都有效,但同时使用两者时则不然。

有什么想法吗???

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

违规声明在ListingServiceProvider中.php内容如下:

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

错误是new AdvertRepository语句。原因是,我们告诉php直接实例化接口"AdvertRepository"。相反,我们需要告诉Laravel实例化"AdvertRepository"接口的适当实现。为此,我们使用 App::make('AdvertRepository') .这样,Laravel使用先前声明的绑定来实例化正确的实现。

如果你的构造函数没有注入类,你必须告诉Laravel当它需要实例化一个特定的接口时将使用哪个类:

将其放入筛选器或绑定文件中:

App::bind('PlaneSaleing'Repositories'Advert'AdvertRepository', function()
{
    return new PlaneSaleing'Repositories'Advert'EloquentAdvert;
});