【问题标题】:Laravel Creating Service provider argument 1 must implement service providerLaravel 创建服务提供者参数 1 必须实现服务提供者
【发布时间】:2015-10-15 18:11:31
【问题描述】:

您好,我正在创建一个自定义缓存服务类,它将从我的存储库中抽象出缓存层。但是,当我收到此错误时,我遇到了一些麻烦:

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

我的课是这样的:

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

}

在我的模型中,我有以下内容;

<?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;
}

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

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

    }


}

任何想法如何正确设置此服务提供程序以在任何模式/控制器/repo 等中使用?

【问题讨论】:

    标签: laravel caching service laravel-4 ioc-container


    【解决方案1】:

    你有没有尝试过这样做:

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

    我刚刚根据旅行评论更新了它

    【讨论】:

    • 我仍然收到此错误 Class 'MyApp\Cache\MyApp\Services\Cache\CacheService' not found 并且必须在 CacheManager 和 $cache 之间添加一个逗号。任何想法出了什么问题?我现在正在使用此代码; $this-&gt;app-&gt;bind('MyApp\Cache\CacheInterface',function(){ return new MyApp\Cache\CacheService(CacheManager, $cache); });
    • 您是否已转储您的数据composer dump 以便他们再次重新生成加载程序?还有一件事你不应该在 CacheManage$cache 之间添加逗号,最后一件事你应该检查你的代码你有一个问题是在 CacheService 构造函数中缺少 $tag 参数
    • 如果您在 return 语句类引用上有前导反斜杠,这可能会起作用:“return new \MyApp\Cache\CacheService(CacheManager $cache);”或者干脆“返回新的 CacheService(CacheManager $cache);”因为您已经在 \MyApp\Cache 命名空间中。缺少前导反斜杠导致 PHP 在错误的位置(“MyApp\Cache\MyAppCache...”)查找您的类。
    • 谢谢@Trip 我刚刚根据你的笔记更新了代码,你是对的。谢谢
    【解决方案2】:

    简短的版本是您不能在 Eloquent 模型上使用依赖注入。 IoC 魔法对它们不起作用,并且由于您的 AbstractModel 扩展了 Eloquent Model 类,因此 IoC 魔法在这里不起作用。 (Taylor Otwell 的部分解释——https://github.com/laravel/framework/issues/3862#issuecomment-37364543

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

    (1) 为模型使用存储库并在那里注入您的 CacheService。由于 Eloquent 是一个类似于存储库的 ORM,因此这可能会令人困惑和乏味。

    (2) 通过一个新的 Facade 注册你的 CacheService 并像 Laravel 的内置 Cache 门面一样使用它,直接在你的模型中而不需要注入 -- MyCache::has($key)。如果您永远不需要连接到两个不同的缓存,它可以设置为单例。 (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

    【讨论】:

      【解决方案3】:

      您试图将实现CacheInterface 的实例注入SprintTask,但在您的服务提供者中,您提供的CacheService 实例未实现CacheInterface

      您需要在CashService 中实现该接口才能将其传递给SpringTask

      class CacheService implements CacheInterface
      

      【讨论】:

        【解决方案4】:

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

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

        这就是您收到错误的原因 - 它只是表示服务容器无法解析 CacheService 类的必需依赖项之一。

        这个问题有多种解决方案。

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

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

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

        如果 $tags 是容器无法管理和注入的东西,您需要自己实例化 CacheService 并使用 bind() 绑定它。 p>

        如果 $tags 是服务容器无法管理的,例如数组,您需要自己实例化 TaskRepository,而不是通过服务容器。

        您可以在此处阅读有关 Laravel 中依赖注入的更多信息:http://laravel.com/docs/5.0/container

        【讨论】:

        • 有 laravel4 文档吗?
        猜你喜欢
        • 1970-01-01
        • 2014-04-20
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 2015-10-24
        • 2016-10-06
        • 1970-01-01
        • 2017-01-11
        相关资源
        最近更新 更多