2014-07-07 29 views
0

我有问题获得依赖注入来处理依赖性反转。我可以在构造函数中调用App :: make,并且依赖性反转工作正常......只有当我尝试将其注入构造函数中时,才会遇到问题。Laravel依赖注入域名空间

ReflectionException Class StationsInterface does not exist 

会打这将是... /统计/站/ mogreet一个URI/6

文件Stucture:

-app 

    -controllers 
     *StatsController 

-Dashboard 

    -Datasync 

     -Interfaces 
      *DatasyncInterface 
      *MogreetDatasyncInterface 

     -Services 
      *MogreetDatasync 

     *BackendServiceProvider 
     *DatasyncBase 

    -Repositories 

     -Interfaces 
      *CredentialsInterface 
      *StationsInterface 

     -Stations 
      *DbCredentials 
      *DbStations 
      *FileCredentials 

     -Stats 

     *BackendServiceProvider 
     *DbRepositoryBase 

相关的代码块如下:

服务提供商:

<?php namespace Dashboard\Repositories; 

use Illuminate\Support\ServiceProvider; 

class BackendServiceProvider extends ServiceProvider { 

    public function register() { 

     // Service Providers located in Stats directory 
     $this->app->bind('StatsDailyInterface', 'Dashboard\Repositories\Stats\DbStatsDaily'); 
     //$this->app->bind('StatsMonthlyRepository', 'Dashboard\Repositories\Stats\DbStatsMonthly'); 
     //$this->app->bind('StatsYearlyRepository', 'Dashboard\Repositories\Stats\DbStatsYearly'); 

     // Service Providers located in Stations directory 
     $this->app->bind('CredentialsInterface', 'Dashboard\Repositories\Stations\FileCredentials'); 
     $this->app->bind('StationsInterface', 'Dashboard\Repositories\Stations\DbStations'); 

    } 

} 

Controller:请注意,在此构造函数中,我使用App :: make而不是注入依赖项。如果我注入依赖关系,就会像我在DatasyncBase类中那样得到一个类解析错误。

<?php 

use Dashboard\ConrollerFacades\Facades\Services; 

class StatsController extends BaseController { 

    /* 
    |-------------------------------------------------------------------------- 
    | Stats Controller 
    |-------------------------------------------------------------------------- 
    | 
    | Pull and display stats for station, market, or corporate views 
    | 
    | 
    | 
    */ 

    private $StationModel; 

    public function __construct() { 
     $this->StationModel = App::make('StationsInterface'); 
    } 

    /** 
    * Pulls stats for an individual station 
    * 
    * @param string $service of station 
    * @param integer $id of station 
    * 
    * @return void 
    */ 
    public function station($service, $stationId) { 

     $this->Service = $this->serviceSelector($service); 

     if(!$this->Service) throw new Exception('Unknown Service Selected', 1); 

     $this->Service->init($stationId); 

     exit(); 

    } 

    /** 
    * Pulls stats for a Market 
    * 
    * @param integer $id of market 
    * 
    * @return void 
    */ 
    public function market($service, $marketId) { 

     $this->Service = $this->serviceSelector($service); 

     if(!$this->Service) throw new Exception('Unknown Service Selected', 1); 

     foreach($StationModel->getStationIdsByMarket($marketId) as $station) { 
      $this->Service->init($station); 
     } 

     exit(); 

    } 

    /** 
    * Pulls stats for Corporate (all stations) 
    * 
    * @return void 
    */ 
    public function corporate($service) { 

     $this->Service = $this->serviceSelector($service); 

     if(!$this->Service) throw new Exception('Unknown Service Selected', 1); 

     foreach($StationModel->getAllStationIds() as $station) { 
      $this->Service->init($station); 
     } 

     exit(); 

    } 

    private function serviceSelector($service) { 

     switch(strtolower($service)) { 
      case 'brightcove': return App::make('BrightCoveDatasyncInterface'); break; 
      case 'facebook': return App::make('FacebookDatasyncInterface'); break; 
      case 'googleanalytics': return App::make('GoogleAnalyticsDatasyncInterface'); break; 
      case 'liquidcompass': return App::make('LiquidCompassDatasyncInterface'); break; 
      case 'mogreet': return App::make('MogreetDatasyncInterface'); break; 
      case 'twitter': return App::make('TwitterDatasyncInterface'); break; 
      default: return false; break; 
     } 

    } 

} 

这个类的构造函数就是依赖注入的问题发生。 DatasyncBase:这个类永远不会被直接实例化,它是由像MogreetDatasync这样的服务类继承的。将构造函数移到MogreetDatasync类进行测试并不能解决问题。

<?php namespace Dashboard\Datasync; 

use Dashboard\Repositories\Interfaces\StationsInterface; 
use Dashboard\Repositories\Interfaces\CredentialsInterface; 

class DatasyncBase { 

    protected $Station; 
    protected $Credentials; 

    protected $results; 

    protected $stats; 

    public function __construct(StationsInterface $Station , CredentialsInterface $Credentials) { 
     $this->Station = $Station; 
     $this->Credentials = $Credentials; 
     $this->stats = array(); 
    } 

    public function __destruct() { 

     unset($this->results); 
     unset($this->stats); 

    } 

    public function init() {} 

    protected function fetch($uri = null, $post_fields = null) { 

     $cURL = curl_init(); 
     curl_setopt($cURL, CURLOPT_URL, $uri); 
     curl_setopt($cURL, CURLOPT_CUSTOMREQUEST, 'GET'); 
     curl_setopt($cURL, CURLOPT_POSTFIELDS, $post_fields); 
     $this->results = curl_exec($cURL); 
     curl_close($cURL); 

    } 

} 

一个数据同步服务:

<?php namespace Dashboard\Datasync\Services; 

use Dashboard\Datasync\DatasyncBase; 
use Dashboard\Datasync\Interfaces\MogreetDatasyncInterface; 

class MogreetDatasync extends DatasyncBase implements MogreetDatasyncInterface { 

    public function init($stationId) {} 
    protected function uri() {} 
    protected function parse() {} 
    protected function write() {} 

} 
+0

你在哪里实例化DatasyncBase类?你是否意识到如果你想让laravel从IOC容器注入依赖关系,你必须使用App :: make()? – jah

+0

DatasyncBase类只是Datasync的父类,所以它通过MogreetDatasync的继承来实例化。我并不知道你必须使用App :: make()来注入依赖关系,大多数例子中我只使用bind。我将开始研究这种方法,但如果您有一个很好的示例/教程,您可以指点我,这将非常感激。 – David

+0

类型提示自动注入是Laravel所做的事情,而不是PHP所做的。您可以从控制器构造函数注入的原因是因为它使用Laravel的IOC容器的build()方法实例化。看看这个班级,你会更好地理解发生了什么。我甚至相信Laracasts有关于它的截屏:) – jah

回答

0

回答这个问题是针对ServiceDatasyncInterfaces关闭。以前我是定义绑定像这样:

$this->app->bind('MogreetDatasyncInterface', 'Dashboard\Datasync\Services\MogreetDatasync'); 

然而,这并不让国际奥委会“递归”注入反转依赖,必须使用App ::化妆(“InversionInterface”)为国际奥委会其实解决这个正确。

<?php namespace Dashboard\Datasync; 

use Illuminate\Support\ServiceProvider; 

use Dashboard\Datasync\Services\BrightCoveDatasync; 
use Dashboard\Datasync\Services\FacebookDatasync; 
use Dashboard\Datasync\Services\GoogleAnalyticsDatasync; 
use Dashboard\Datasync\Services\LiquidCompassDatasync; 
use Dashboard\Datasync\Services\MogreetDatasync; 
use Dashboard\Datasync\Services\TwitterDatasync; 

class BackendServiceProvider extends ServiceProvider { 

    public function register() { 

     $this->app->bind('BrightCoveDatasyncInterface', function() { return new BrightCoveDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 
     $this->app->bind('FacebookDatasyncInterface', function() { return new FacebookDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 
     $this->app->bind('GoogleAnalyticsDatasyncInterface', function() { return new GoogleAnalyticsDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 
     $this->app->bind('LiquidCompassDatasyncInterface', function() { return new LiquidCompassDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 
     $this->app->bind('MogreetDatasyncInterface', function() { return new MogreetDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 
     $this->app->bind('TwitterDatasyncInterface', function() { return new TwitterDatasync($this->app->make('StationsInterface'), $this->app->make('CredentialsInterface')); }); 

    } 

} 

这是一个相当小的问题,但是您需要在包含正在注入的类的文件中使用正确的接口。我DatasyncBase文件现在看起来是这样的:

<?php namespace Dashboard\Datasync; 

use Dashboard\Repositories\Interfaces\StationsInterface; 
use Dashboard\Repositories\Interfaces\CredentialsInterface; 

class DatasyncBase { 

    protected $Station; 
    protected $Credentials; 

    protected $results; 

    protected $stats; 

    public function __construct(StationsInterface $Station, CredentialsInterface $Credentials) { 
     $this->Station = $Station; 
     $this->Credentials = $Credentials; 
     $this->stats = array(); 
    } 

    public function __destruct() { 

     unset($this->results); 
     unset($this->stats); 

    } 

    public function init() {} 

    protected function fetch($uri, $post_fields = '') { 

     $cURL = curl_init(); 
     curl_setopt($cURL, CURLOPT_URL, $uri); 
     curl_setopt($cURL, CURLOPT_CUSTOMREQUEST, 'GET'); 
     curl_setopt($cURL, CURLOPT_POSTFIELDS, $post_fields); 
     $this->results = curl_exec($cURL); 
     curl_close($cURL); 

    } 

} 

你可以找到更多的ServiceProvider的位置: https://laracasts.com/lessons/service-providers-decoded