首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel创建服务提供者参数1必须实现服务提供者

Laravel创建服务提供者参数1必须实现服务提供者
EN

Stack Overflow用户
提问于 2015-07-24 23:24:36
回答 4查看 1.2K关注 0票数 4

嗨,我正在创建一个自定义缓存服务类,它将把缓存层从我的存储库中抽象出来。然而,当我遇到这个错误时,我遇到了一些麻烦:

Argument 1 passed to Task::__construct() must implement interface MyApp\Cache\CacheInterface, none given, called in /var/www/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 792 and defined

我的课程如下:

代码语言:javascript
复制
<?php namespace MyApp\Cache;

use Illuminate\Cache\CacheManager;

class CacheService {

 /**
  * @var Illuminate\Cache\CacheManager
  */
  protected $cache;

  /**
   * @var integer
   */
  protected $minutes;

  /**
   * Construct
   *
   * @param Illuminate\Cache\CacheManager $cache
   * @param string $tag
   * @param integer $minutes
   */
  public function __construct(CacheManager $cache, $minutes = 60)
  {
    $this->cache = $cache;
    $this->tag = $tag;
    $this->minutes = $minutes;
  }

  /**
   * Get
   *
   * @param string $key
   * @return mixed
   */
  public function get($key)
  {
    return $this->cache->tags($this->tag)->get($key);
  }

  /**
   * Put
   *
   * @param string $key
   * @param mixed $value
   * @param integer $minutes
   * @return mixed
   */
  public function put($key, $value, $minutes = null)
  {
    if( is_null($minutes) )
    {
      $minutes = $this->minutes;
    }

    return $this->cache->tags($this->tag)->put($key, $value, $minutes);
  }

  /**
   * Has
   *
   * @param string $key
   * @return bool
   */
  public function has($key)
  {
    return $this->cache->tags($this->tag)->has($key);
  }

}

在我的模型中,我有以下几点;

代码语言:javascript
复制
<?php
use Abstracts\Model as AbstractModel;
use Illuminate\Support\Collection;
use CMS\APIv2\Objects\Entity;
use MyApp/Cache\CacheInterface;

class SprintTask extends AbstractModel
{


    /**
     * @var CacheInterface
     */
    protected $cache;

    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }


public static function scopegetAssignedSprint($id) {
    $key = md5('id.'.$id.get_class());

    if($this->cache->has($key))
    {
        return $this->cache->get($key);
    }

    $user = static::where('uid', $id)->lists('sprint_id');

    $this->cache->put($key, $user);

    return $user;
}

我有一个缓存服务提供者,如下所示;

代码语言:javascript
复制
<?php
namespace MyApp\Cache;

use MyApp\Cache\CacheInterface;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Register
     */
    public function register()
    {

        $this->app->bind
        ('MyApp\Cache\CacheInterface',
            'MyApp\Cache\CacheService');

    }


}

有什么想法吗?我怎样才能正确地设置这个服务提供者,以便在任何模式/控制器/回购等中使用?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-10-31 06:23:55

你试过这样做吗?

代码语言:javascript
复制
<?php
namespace MyApp\Cache;

use MyApp\Cache\CacheInterface;
use Illuminate\Support\ServiceProvider;
use Illuminate\Cache\CacheManager;

class CacheServiceProvider extends ServiceProvider
{

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Register
     */
    public function register()
    {

        $this->app->bind('MyApp\Cache\CacheInterface',function(){
            return new CacheService(CacheManager $cache);
        });

    }
}

我刚刚根据Trip评论更新了它

票数 1
EN

Stack Overflow用户

发布于 2015-07-24 23:43:55

当服务容器试图实例化TaskRepository,时,它会看到它的一个构造器参数是类CacheService的对象。因此,它首先尝试实例化这个对象,以便以后可以将它传递给TaskRepository构造函数。

CacheService定义了两个必需的参数。当容器试图实例化CacheService时,它需要为这两个属性提供值并将它们传递给构造函数。服务容器通常使用构造函数参数的类型提示来确定应该注入什么服务。在您的示例中,需要传递$tag变量,但是由于它在构造函数签名中没有类型提示,因此服务容器不知道应该向构造函数传递什么。

这就是您得到错误的原因--它简单地说服务容器无法解决CacheService类所需的依赖关系之一。

这个问题有多种解决办法。

首先,您需要向$tags参数添加一个类型提示。

如果$tags是某个服务容器能够实例化的类的对象,则向CacheService构造函数签名中添加类型提示。

如果实例化$tags对象是您自己想要处理的东西,那么在您的服务提供者中创建对象并使用容器的 bind ()方法绑定它。

如果$tags是不能由容器管理和注入的,则需要自己实例化CacheService并使用 bind ()绑定它。

如果$tags不能由服务容器(例如数组)管理,则需要自己实例化TaskRepository,而不是通过服务容器实例化TaskRepository。

您可以在Laravel中阅读更多关于依赖注入的内容:http://laravel.com/docs/5.0/container

票数 1
EN

Stack Overflow用户

发布于 2015-11-06 07:21:45

简短的版本是,您不能在雄辩的模型上使用依赖注入。IoC魔术不适用于它们,而且由于您的AbstractModel扩展了雄辩的模型类,所以IoC魔术在这里不起作用。(泰勒·奥特威尔的部分解释- https://github.com/laravel/framework/issues/3862#issuecomment-37364543)

有几种方法可以让这个基本想法发挥作用:

(1)为模型使用一个存储库,并在那里注入您的CacheService。因为雄辩是一个资源库一样的ORM,这可能是混乱和乏味的。

(2)通过一个新的外观注册您的CacheService,并像Laravel内置的缓存外观那样使用它,直接在您的模型中使用它而不需要注入- MyCache::has($key)。如果您不需要连接到两个不同的缓存,则可以将其设置为Singleton。(L4:http://laravel.com/docs/4.2/facades,L5:http://laravel.com/docs/5.1/facades)

(3)使用#1和#2的组合,如下所示:http://dfg.gd/blog/decoupling-your-code-in-laravel-using-repositiories-and-services

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31621232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档