2014-01-23 100 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

    您的编辑未保存。但是我并没有谈论我看到的代码,而是你打算如何使用这个包,这会影响你构建包的方式。刚编辑回答更多。 –

    相关问题