接口laravel不绑定为什么?(Interface laravel doesn't bin

2019-10-19 06:13发布

好家伙我创建一个包,我是想实现我的班,但没有成功依赖注入。 我跟所有做它的工作指令。 我得到它的疯狂。 当我尝试调用

Player::team_players(2);

它把我的错误:

传递给团队\播放器\播放器参数1 :: __构造()必须是团队\播放器\ StatusPlayerInterface的实例,但没有给出,称为C:\ WAMP \ WWW \最美\工作台\队伍\球员的\ src \队伍\播放器\ PlayerServiceProvider.php上线35和限定

我创建了类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它应该自动调用称为实例的功能团队。 这种方法用于不做

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
  }

}

但我可以抛出的接口传递给构造函数并只返回接口的功能团队,因为该接口与合同类似,因此可以相信,存在该功能。 但问题是,我找不到传递的构造函数接口的方式。

Answer 1:

在这里你的构造正在等待$球员:

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)我不知道,国际奥委会将在该点的代码的有效,就必须问泰勒Otwell自己。

但是,这是你可以这样做:

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容器有其界限,有一些决议,也不会解决,仅仅因为他们是你的体系结构的问题。

编辑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);

这就是所有你需要做它的工作,真的。 该错误会自行消失。 但是,你需要这个包过工作,这恐怕是不够的。

正如我之前所说, 如果国际奥委会能在这里工作,你怎么可能让它发出正确的执行活动,退休或受伤,当时你需要什么? 我看到两个选项:

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)更改架构,让你在良好的跟踪,在情况下,开闭原则。

采取对工厂设计模式的读取,它可以帮助您与此achitecture。 这是一个关于它的答案: 什么是PHP中的工厂设计模式? 。



文章来源: Interface laravel doesn't bind why?