您好我正在创建一个自定义缓存服务类,它将缓存层从我的存储库中抽象出来。但是,由于我收到此错误,我遇到了一些麻烦:
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');
}
}
如何正确设置此服务提供程序以在任何模式/控制器/存储库等中使用?
答案 0 :(得分:1)
当服务容器尝试实例化 TaskRepository 时,它会看到其构造函数参数之一是类 CacheService 的对象。因此,它首先尝试实例化此对象,以便稍后可以将其传递给 TaskRepository 构造函数。
您的 CacheService 定义了两个必需参数。当Container尝试实例化 CacheService 时,它需要为这两个属性提供值并将它们传递给构造函数。服务容器通常使用构造函数参数的类型提示来标识应注入的服务。在您的情况下,您需要传递 $ tag 变量,但由于它在构造函数签名中没有类型提示,因此服务容器不知道应该将什么传递给构造函数。
这就是您收到错误的原因 - 它只是说服务容器无法解析 CacheService 类所需的依赖项之一。
该问题有多种解决方案。
首先,您需要为 $ tags 参数添加类型提示。
如果$ tags是服务容器能够实例化的某个类的对象,则向CacheService构造函数签名添加类型提示。
如果想要自己实例化 $ tags 对象,请在您的某个服务提供商中创建对象,并使用容器的 bind()方法绑定它。
如果 $ tags 是无法通过容器管理和注入的东西,则需要自己实例化CacheService并使用 bind()绑定它。
如果 $ tags 是服务容器无法管理的内容,例如数组,您需要自己实例化TaskRepository,而不是通过服务容器实现。
您可以在此处阅读有关Laravel中依赖注入的更多信息:http://laravel.com/docs/5.0/container
答案 1 :(得分: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);
});
}
}
我刚刚根据旅行评论更新了
答案 2 :(得分:1)
简短版本是您不能在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 facade一样使用它,直接在你的模型中不注入--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
答案 3 :(得分:-1)
您正在尝试将实施CacheInterface
的实例注入SprintTask
,但在您的服务提供商中,您提供的CacheService
实例未实现CacheInterface
}。
您需要在CashService
中实现该界面,以便能够将其传递给SpringTask
:
class CacheService implements CacheInterface