接口laravel不绑定为什么? [英] Interface laravel doesn't bind why?

查看:75
本文介绍了接口laravel不绑定为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在创建一个程序包,并且试图在我的类上实现依赖项注入而没有成功.我按照所有说明进行操作.我对此感到疯狂. 当我尝试致电

Hello guys I was creating a package and i was trying to implement a dependency injection on my class without success. I followed all the instruction for do it work. I'm getting crazy on it. When i try to call

Player::team_players(2);

它给我抛出一个错误:

传递给Team \ Player \ Player :: __ construct()的参数1必须是 Team \ Player \ StatusPlayerInterface的实例,未给出,在 C:\ wamp \ www \ ultima \ workbench \ team \ player \ src \ Team \ Player \ PlayerServiceProvider.php 在第35行并已定义

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');
        });
    }

我正在尝试遵循Jeffrey Way建议遵循的原则.它说 实体应该开放以进行扩展,但封闭以进行修改.

What i'm trying to do is to follow a principle that Jeffrey Way suggested to follow. It say Entities should be open for extension but close for modification.

我还有另外2个实现StatusPlayerInterface的类,当然,仅更改函数team()上的查询

I 2 others classes that implements StatusPlayerInterface and of course change only the query on the function team()

  • 在示例中处于活动状态
  • 已退休
  • 受伤

然后我有一个主要类 Player ,并使用 team_players 方法,它应该自动调用被调用实例的功能团队.这种方法用于不做

Then i have the main class Player and with the method team_players it should automatically call the function team of the instance called. this method is used for don't do

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
  }

}

但是我可以将接口传递给构造函数,并只返回接口的函数组,因为接口就像一个契约,因此它可以信任存在该函数的接口.但是问题是我找不到在构造函数上传递该接口的方法.

but i can throw pass the interface to the constructor and return just the function team of the interface, because the interface is like a contract so it can trust that exist that function. But the problem is that i cannot find a way for pass that interface on the constructor.

推荐答案

您的构造函数正在等待$ player:

Your constructor here is waiting for a $player:

class Player {

  ...

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

}

因此,您的ServiceProvider应该在第35行中传递一个给它:

So your ServiceProvider should be passing one to it in line 35:

return new Player; // line 35

我可以看到您尝试使用IoC为您做到这一点:

I can see you tried to use IoC to do that for you:

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

但是您有两个问题,

1)Team\Player\Player不实现Team\Player\StatusPlayerInterface,而必须实现.但是Active类确实实现了,您不应该使用它吗?

1) Team\Player\Player doesn't implements Team\Player\StatusPlayerInterface and it must. But Active class does implements, shouldn't you be using it?

2)我不确定IoC在代码的这一点上是否有效,必须询问Taylor Otwell本人.

2) I'm not sure that the IoC will be effective at this point of the code, would have to ask Taylor Otwell himself.

但这是您可以做的:

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');
    });
}

您的Player类必须实现StatusPlayerInterface:

Your Player class would have to implement the StatusPlayerInterface:

class Player implements StatusPlayerInterface {

}

但是我不确定是否应该这样做,所以,看,这些是建议,我不知道您对包装的确切使用,所以我只是指出我所看到的是错误的就可以了吗?

But I'm not sure if it is supposed to, so, look, those are suggestions, I not aware of what you're doing exactly with your package, so I'm just pointing what I'm seeing is wrong on it, okay?

编辑

例如,您正在构造已经通过Player状态的Player类,对吗?但是,如果构造方法(构建方式)仅接收通过ServiceProvider传递的状态,您将如何交换不同的状态?在这种情况下,IoC容器将无济于事,因为您应该能够以3种不同的状态实例化同一班级:活跃,退休和受伤.

For example, you are constructing your Player class already passing a Player Status, right? But how would you swap different statuses if the constructor, the way you're building, will only receive the one you are passing via your ServiceProvider? In this case the IoC container will not help you, because you should be able to instantiate that same class with 3 differents statuses: active, retired and injured.

您可以创建一个setPlayerStatus()方法,当然要在请求期间进行更改,但是正如我希望看到的那样,在构建整个程序包之前,您必须首先考虑一下体系结构,然后再考虑以此为基础编写代码,始终记住IoC容器有其边界,并且有一些解决方案只是因为它们是您的体系结构上的问题而无法解决.

You can create a setPlayerStatus() method, to change it in the during a request, of course, but as I hope you can see, before building the whole package, you have first to think a lot about your architecture and then write your code based on it, always remembering that the IoC container has its boundaries and there are some resolutions it will not solve, just because they are problems on your architecture.

编辑2

您实际上并没有将接口传递给构造函数.您传递实现该接口的具体类的具体对象.

You don't really pass an interface to a constructor. You pass a concrete object of a concrete class that implemented that interface.

再次查看错误,它说出3件重要的事情

Look at the error again, it says 3 important things

Argument 1 passed to Team\Player\Player::__construct() 

must be an instance of Team\Player\StatusPlayerInterface, 

none given

所以您需要实例化Player

So you need to instantiate Player

return new Player;

有东西:

return new Player(new Active);

这真的是使它工作所需的全部.错误将消失.但是您也需要此程序包才能工作,恐怕这还不够.

That's all you need to make it work, really. The error will go away. But you need this package to work too and I'm afraid this is not enough.

正如我之前说的,如果,IoC可以在这里工作,您如何使其在需要时发送活动",退休"或受伤"的正确实现?我看到两个选择:

As I said before, if the IoC could work here, how could you make it send the correct implementation of Active, Retired or Injured, at the time you need? I see two options:

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');

每次都需要其中之一,这很糟糕.

every time you need one of them, which is bad.

2)在开放式封闭原则"的情况下,更改体系结构以使您处于SOLID轨道.

2) Change the architecture to keep you in the SOLID track, in the case the Open Closed Principle.

阅读工厂设计模式",它可能会帮助您解决此问题.这是一个答案: PHP中的工厂设计模式是什么? .

Take a read on the Factory Design Pattern, it might help you out with this achitecture. This is an answer about it: What is a Factory Design Pattern in PHP?.

这篇关于接口laravel不绑定为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆