Php Laravel 4中的Facade和注入依赖性问题
我遇到了一个问题,那就是如何让一个Facade与注入底层类的依赖项一起正常工作 我有一个叫做“Listing”的类。它有一个称为“AdverRepository”的依赖项,它是一个接口,还有一个称为EloquentAdvert的类,它实现该接口。这三个类的代码如下所示: //PlaneSaleing\Providers\Listing.phpPhp Laravel 4中的Facade和注入依赖性问题,php,dependency-injection,laravel-4,facade,service-provider,Php,Dependency Injection,Laravel 4,Facade,Service Provider,我遇到了一个问题,那就是如何让一个Facade与注入底层类的依赖项一起正常工作 我有一个叫做“Listing”的类。它有一个称为“AdverRepository”的依赖项,它是一个接口,还有一个称为EloquentAdvert的类,它实现该接口。这三个类的代码如下所示: //PlaneSaleing\Providers\Listing.php <?php namespace PlaneSaleing\Providers; use PlaneSaleing\Repositories\Adv
<?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";
}
}
现在,我创建了一个用于列表的外观。我添加了一个新外观,如下所示,并在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';
}
}
如果构造函数没有被注入类,则必须告诉Laravel在需要实例化特定接口时将使用什么类:
将其放入筛选器或绑定文件:
App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', function()
{
return new PlaneSaleing\Repositories\Advert\EloquentAdvert;
});
好的,我已经解决了…对于那些遇到类似问题的人
ListingServiceProvider.php中的违规语句如下:
$this->app['Listing'] = $this->app->share(function() {
return new Listing(new AdvertRepository);
});
错误是newadvertreepository
语句。原因是,我们告诉php直接实例化接口“AdvertRepository”。相反,我们需要告诉Laravel实例化“AdvertRepository”接口的适当实现。为此,我们使用App::make('AdertRepository')
。通过这种方式,Laravel使用先前声明的绑定来实例化正确的实现。但是我的ListingServiceProvider文件中有这个(或类似的代码)…?是的,但我会尝试一下,因为Laravel仍然不知道如何实例化该存储库。由于您的facade正在工作,它应该被绑定,但您仍然会遇到此错误,因此,该特定绑定有问题。您建议我在哪里插入该代码(在我的服务提供商的顶部)?我会尝试将其添加到app/start/global.php,有一些(singleton)绑定已经存在了……我不确定这是否是您确切的意思,但请记住,Facades是依赖注入的替代品,通常不与依赖注入结合使用。如果您想使用DI,请将类注入到Facade的底层,而不是Facade本身。根据你的回答,我认为你理解这一点,但我想指出。对不起,你能告诉我你到底做了什么吗?我遇到了完全相同的问题。因此,您没有使用new advert repository
而是做了什么?你把App::make('advertreepository')
放在哪里了?你是如何返回新列表的?
use PlaneSaleing\Providers\Listing;
class TestController extends BaseController {
protected $listing;
public function __construct(Listing $listing) {
$this->listing = $listing;
}
public function test1() {
$this->listing->test();
}
}
<?php namespace PlaneSaleing\Providers;
use Illuminate\Support\Facades\Facade;
class ListingFacade extends Facade {
protected static function getFacadeAccessor() {
return 'Listing';
}
}
<?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);
});
}
}
App::bind('PlaneSaleing\Repositories\Advert\AdvertRepository', function()
{
return new PlaneSaleing\Repositories\Advert\EloquentAdvert;
});
$this->app['Listing'] = $this->app->share(function() {
return new Listing(new AdvertRepository);
});