我遇到一个问题,让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数组中现在,如果我将List作为依赖项注入控制器并调用测试方法(如下所示),Laravel会正确检测依赖项,通过其绑定实例化EloquentAdvert并显示“这已经有效”。
// Controllers / 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创建了一个facade。我添加了一个新的Facade,如下所示,并在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和装订在单独测试时都有效,但在两者同时使用时都没有。
任何想法???
答案 0 :(得分:3)
好的,所以我已经弄明白......对于那些遇到类似问题的人......
违规声明在ListingServiceProvider.php中,内容如下:
$this->app['Listing'] = $this->app->share(function() {
return new Listing(new AdvertRepository);
});
错误是new AdvertRepository
语句。原因是,我们告诉php直接实例化接口'AdvertRepository'。相反,我们需要告诉Laravel实例化“AdvertRepository”接口的适当实现。为此,我们使用App::make('AdvertRepository')
。这样,Laravel使用先前声明的绑定来实例化正确的实现。
答案 1 :(得分:0)
如果构造函数没有注入类,则必须告诉Laravel在需要实例化特定接口时将使用哪个类:
将它放在过滤器或绑定文件中:
App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', function()
{
return new PlaneSaleing\Repositories\Advert\EloquentAdvert;
});