Laravel不希望在服务提供者中自动注入依赖项

时间:2015-10-28 18:27:35

标签: php laravel laravel-5

我有一个服务提供商:

<?php namespace App\Providers;

use Carbon\Carbon;

use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Cache\Store;

use File;

use App\Models\Translation;

class ModuleTranslationsServiceProvider extends ServiceProvider {

    protected $cache;

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

    /**
     * Load the config from the database.
     *
     * @return void
     */
    public function register()
    {
        $translations = $this->cache->remember('translations', function() {
            //Load and return translations.
        });
        $this->app->singleton('translations', function($app) use ($translations) {
            return $translations;
        });
    }

}

但是,当应用程序运行时(工匠或浏览器),我收到以下错误:

ErrorException]                                                                                                                                                                                                                                                                        
  Argument 1 passed to App\Providers\ModuleTranslationsServiceProvider::__construct() must be an instance of Illuminate\Contracts\Cache\Store, instance of Illuminate\Foundation\Application given, called in /home/user/projects/AppPlatform/vendor/laravel/framework/  
  src/Illuminate/Foundation/ProviderRepository.php on line 150 and defined                                                                                                                                                                                                                

通常,Laravel通过构造函数自动注入合同。这是服务提供商的限制吗?或者我做错了吗?

修改

我更改了代码以反映Iamzozo的建议:

public function boot(Store $cache) {
    $this->cache = $cache;
}

但这只是回归:

[Symfony\Component\Debug\Exception\FatalErrorException]  
Call to a member function remember() on null    

所以我尝试从应用程序实例化:

$cache = $this->app['Illuminate\Cache\CacheManager'];

但这只是回归:

[ReflectionException]       
Class cache does not exist

试图实例化合同:

$cache = $this->app['Illuminate\Contracts\Cache\Store'];         

给我一​​个:

[Illuminate\Container\BindingResolutionException]               
Target [Illuminate\Contracts\Cache\Store] is not instantiable.  

我知道的最后一件事:使用立面:

use Cache;
//...
$translations = Cache::remember( [...]

但这又会返回:

[Symfony\Component\Debug\Exception\FatalErrorException]                
Call to undefined method Illuminate\Support\Facades\Cache::remember()  

所以我检查了我的提供者数组:

'providers' => [

    /*
     * ...
     */
    'Illuminate\Cache\CacheServiceProvider',
    /*
     * ...
     */
    'App\Providers\ModuleTranslationsServiceProvider',
],

所以缓存是在我的服务提供商之前加载的。

此时我没有新想法。

php版本是通过Apache在PHP-FPM上运行的5.6.14。 Laravel版本是5.0。

1 个答案:

答案 0 :(得分:1)

也许我不清楚我的答案,所以我更新了整体,这个解决方案适用于Laravel 5.1:

<?php namespace App\Providers;

use Carbon\Carbon;

use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Cache\CacheManager as Cache;

use File;

use App\Models\Translation;

class ModuleTranslationsServiceProvider extends ServiceProvider {

    /**
     * Load the config from the database.
     *
     * @return void
     */
    public function register()
    {
        // Update for redis:
        $this->app->register(\Illuminate\Redis\RedisServiceProvider::class);

        $cache = new Cache($this->app);
        $translations = $cache->remember('translations', function() {
            //Load and return translations.
        });
        $this->app->singleton('translations', function($app) use ($translations) {
            return $translations;
        });
    }
}

我没有意识到,Cache\Store您尝试使用的是界面。