我在使外观正常工作时遇到问题,并将依赖项注入到底层类中。
我有一个名为"列表"的课程。它有一个名为"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;
});