2014-07-07 89 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