2014-01-23 57 views
1

你好我正在創建一個包,我試圖在我的類上實現依賴注入而沒有成功。我遵循所有的指示去做它的工作。我越來越瘋狂。 當我嘗試調用接口laravel不綁定爲什麼?

Player::team_players(2); 

扔我一個錯誤:

Argument 1 passed to Team\Player\Player::__construct() must be an instance of Team\Player\StatusPlayerInterface, none given, called in C:\wamp\www\ultima\workbench\team\player\src\Team\Player\PlayerServiceProvider.php on line 35 and defined

我創造了我的課Player.php

<?php namespace Team\Player; 

use Team\Player\Models\User; 
use Team\Player\Models\Team; 
use Team\Player\Models\Fighter; 
use Team\Player\StatusPlayerInterface; 
use DB; 

class Player { 

    protected $player; 

    function __construct(StatusPlayerInterface $player) { 
    $this->player = $player; 
    } 

    public function team_players($team_id) { 
    return $player->team($team_id); 
    } 
} 

StatusPlayerInterface.php

<?php namespace Team\Player; 

interface StatusPlayerInterface { 

    public function team($team_id); // active - retired - injured by team id 

} 

Active.php

<?php namespace Team\Player; 

use Team\Player\Models\User; 
use Team\Player\Models\Team; 
use Team\Player\Models\Fighter; 

/** 
* 
*/ 
class Active implements StatusPlayerInterface 
{ 

    protected $user; 
    protected $team; 
    protected $fighter; 

    function __construct(User $user,Team $team,Fighter $fighter) 
    { 
     $this->user = $user; 
     $this->team = $team; 
     $this->fighter = $fighter; 
    } 

    public function team($team_id) 
    { 
     return $fighters = $this->fighter->with('user')->where('team_id',$team_id)->active()->Confirmed()->get(); 
    } 

} 

PlayerServiceProvider.php

public function register() 
    { 

     $this->app->bind('Team\Player\StatusPlayerInterface','Team\Player\Player'); // bind the interface 
     $this->app['player'] = $this->app->share(function($app) 
      { 
      return new Player; // line 35 
      }); 

     $this->app->booting(function() 
     { 
      $loader = \Illuminate\Foundation\AliasLoader::getInstance(); 
      $loader->alias('Player', 'Team\Player\Facades\Player'); 
     }); 
    } 

編輯:

我想要做的是遵循一個原則,即傑弗裏建議遵循的方式。它說 實體應該開放延期,但關閉修改。

I 2人類,對退役

  • 受傷
  • 的例子

  • 實現StatusPlayerInterface,當然改變的只是查詢的功能團隊()

    • 活動//然後我有主類球員和方法team_players它sh應該自動調用實例調用的功能團隊。這種方法用於不做

      class Player { 
      
      .... 
      
          function team_player($team_id,$status) { 
           if (is_a($status) == "Active") { 
            $fighters = $this->fighter->with('user')->where('team_id',$team_id)->active()->Confirmed()->get(); 
           } elseif(is_a($status) == "Retired") { 
            $fighters = $this->fighter->with('user')->where('team_id',$team_id)->retired()->Confirmed()->get(); 
           } 
          // ecc 
          } 
      
      } 
      

      ,但我可以拋出的接口傳遞給構造函數並只返回接口的功能團隊,因爲該接口與合同類似,因此可以相信,存在即功能。但問題是我找不到在構造函數中傳遞該接口的方法。

  • 回答

    4

    你這裏的構造正在等待$球員:

    class Player { 
    
        ... 
    
        function __construct(StatusPlayerInterface $player) { 
        $this->player = $player; 
        } 
    
    } 
    

    所以,你的ServiceProvider應傳遞一個到它在第35行:

    return new Player; // line 35 
    

    我可以看到你嘗試過使用國際奧委會爲你做的:

    $this->app->bind('Team\Player\StatusPlayerInterface','Team\Player\Player'); 
    

    但是,你有兩個問題,

    1)Team\Player\Player不執行Team\Player\StatusPlayerInterface它必須。但Active類確實實現,你不應該使用它嗎?

    2)我不確定IoC在代碼的這一點是否有效,不得不問泰勒奧特維爾自己。

    不過這是後話,你可以這樣做:

    public function register() 
    { 
        $this->app['player'] = $this->app->share(function($app) 
         { 
         return new Player(new Team\Player\Player); 
    
         //// OR 
    
         return new Player(new Team\Player\Active); 
         }); 
    
        $this->app->booting(function() 
        { 
         $loader = \Illuminate\Foundation\AliasLoader::getInstance(); 
         $loader->alias('Player', 'Team\Player\Facades\Player'); 
        }); 
    } 
    

    您的播放器類必須實現StatusPlayerInterface:

    class Player implements StatusPlayerInterface { 
    
    } 
    

    但我不知道是否應該,所以,看,這些是建議,我不知道你在做什麼你的包,所以我只是指出我所看到的是錯誤的,好嗎?

    編輯

    比如,你正在構建您的播放器類已傳遞一個球員的狀態,對不對?但是如果你構建的構造函數只會接收到你通過ServiceProvider傳遞的構造函數,那麼你將如何交換不同的狀態?在這種情況下,IoC容器不會對您有所幫助,因爲您應該能夠使用3種不同的狀態實例化同一個類:活動,退休和受傷。

    你可以創建一個setPlayerStatus()方法,當然在請求期間改變它,但是正如我希望你能看到的那樣,在構建整個包之前,你首先要考慮很多關於你的架構,然後寫你的代碼基於它,總是記住IoC容器有它的邊界,並且有一些解決方案不會解決,只是因爲它們是你架構上的問題。

    EDIT 2

    你真的不通過一個接口來構造。你傳遞一個實現了這個接口的具體類的具體對象。

    看一次錯誤,它說3周重要的事情

    Argument 1 passed to Team\Player\Player::__construct() 
    
    must be an instance of Team\Player\StatusPlayerInterface, 
    
    none given 
    

    所以,你需要實例球員

    return new Player; 
    

    的東西:

    return new Player(new Active); 
    

    這就是你需要讓它工作,真的。錯誤將消失。但是你也需要這個軟件包,我恐怕這還不夠。

    正如我之前所說,如果 IoC可以在這裏工作,你怎麼能讓它在你需要的時候發送正確的活動,退休或受傷實施?我看到兩個選項:

    1)調用

    $this->app->bind('Team\Player\StatusPlayerInterface','Team\Player\Active'); 
    $this->app->bind('Team\Player\StatusPlayerInterface','Team\Player\Retired'); 
    $this->app->bind('Team\Player\StatusPlayerInterface','Team\Player\Injured'); 
    

    每次你需要他們的一個時間,這是不好的。

    2)更改體系結構以使您保持在SOLID軌道中,在開放閉合原則的情況下。

    閱讀工廠設計模式,它可能會幫助你解決這個問題。這是關於它的一個答案:What is a Factory Design Pattern in PHP?

    +0

    謝謝你的答案,像往常一樣清晰。我只是編輯我的問題,我很確定你可以更好地理解我想要做的事情。 – Fabrizio

    +0

    已更新Cheerse! – Fabrizio

    +0

    您的編輯未保存。但是我並沒有談論我看到的代碼,而是你打算如何使用這個包,這會影響你構建包的方式。剛編輯回答更多。 –

    相關問題