没有依赖注入的Laravel外观类型错误

时间:2018-03-13 10:41:54

标签: php laravel laravel-5.5

我正在尝试从我的应用中的任何位置访问某个功能。但是我收到以下错误:

  

类型错误:参数1传递给   App \ Helpers \ AwsAutoscale :: __ construct()必须是。的实例   Aws \ AutoScaling \ AutoScalingClient,没有给出,调用   第31行/home/vagrant/Site/app/Providers/AwsAutoscaleProvider.php

我的代码是:

应用/助手/ AwsAutoscale.php

<?php

namespace App\Helpers;

use Aws\AutoScaling\AutoScalingClient;

class AwsAutoscale
{

    private $awsClient;

    public function __construct(AutoScalingClient $awsClient)
    {
        $this->awsClient = $awsClient;
    }

    public function groupStats()
    {
        $result = $this->awsClient->describeAutoScalingGroups();

        return collect([
            'desired' => $result['AutoScalingGroups'][0]['DesiredCapacity'],
            'min' => $result['AutoScalingGroups'][0]['MinSize'],
            'max' => $result['AutoScalingGroups'][0]['MaxSize'],
            'current' => count($result['AutoScalingGroups'][0]['Instances'])
        ]);
    }

}

应用/提供者/ AutoScalingClientProvider.php

<?php

namespace App\Providers;

use Aws\AutoScaling\AutoScalingClient;
use Illuminate\Support\ServiceProvider;

class AutoScalingClientProvider extends ServiceProvider
{
    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(AutoScalingClient::class, function () {
            return new AutoScalingClient([
                'AutoScalingGroupName' => config('aws.auto_scaling_client.name'),
                'region' => config('aws.auto_scaling_client.region'),
                'version' => config('aws.auto_scaling_client.version')
            ]);
        });

    }

}

应用/提供者/ AwsAutoScaleProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AwsAutoscaleProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
        $this->app->bind('autoscale', function()

        {

            return new \App\Helpers\AwsAutoscale;

        });
    }
}

配置/ app.php:

'providers' => [
    ...
    App\Providers\AwsAutoscaleProvider::class
    ...

'aliases' => [
    ...
    'autoscale'=> App\Facades\AutoscaleFacade::class,
    ...

控制器中的代码:

return autoscale::groupStats();

调用此结果会导致错误:

  

类型错误:参数1传递给   App \ Helpers \ AwsAutoscale :: __ construct()必须是。的实例   Aws \ AutoScaling \ AutoScalingClient,没有给出,调用   第31行/home/vagrant/Site/app/Providers/AwsAutoscaleProvider.php

1 个答案:

答案 0 :(得分:2)

假设您在AwsAutoscale内保存了此App/Helpers/AwsAutoscale.php个助手:

<?php

namespace App\Helpers;

use Aws\AutoScaling\AutoScalingClient;

class AwsAutoscale
{
    private $awsClient;

    public function __construct(AutoScalingClient $awsClient)
    {
        $this->awsClient = $awsClient;
    }

    public function groupStats()
    {
        $result = $this->awsClient->describeAutoScalingGroups();

        return collect([
            'desired' => $result['AutoScalingGroups'][0]['DesiredCapacity'],
            'min' => $result['AutoScalingGroups'][0]['MinSize'],
            'max' => $result['AutoScalingGroups'][0]['MaxSize'],
            'current' => count($result['AutoScalingGroups'][0]['Instances']),
        ]);
    }
}

您希望通过Facade访问此AwsAutoscale类实例。第一步是在service provider内注册。我们将它放在App/Providers/AutoScalingClientProvider.php文件中:

<?php

namespace App\Providers;

use App\Helpers\AwsAutoscale;
use Aws\AutoScaling\AutoScalingClient;
use Illuminate\Support\ServiceProvider;

class AutoScalingClientProvider extends ServiceProvider
{
    public function register()
    {
        // Bind the AutoScalingClient.
        $this->app->bind(AutoScalingClient::class, function () {
            return new AutoScalingClient([
                'AutoScalingGroupName' => config('aws.auto_scaling_client.name'),
                'region' => config('aws.auto_scaling_client.region'),
                'version' => config('aws.auto_scaling_client.version')
            ]);
        });

        // Bind the AwsAutoscale helper.
        $this->app->singleton('autoscale', function ($app) {
            // You need to manually inject the dependency, which is the AutoScalingClient instance
            return new AwsAutoscale($app->make(AutoScalingClient::class));
        });
    }
}

您可以删除App/Providers/AwsAutoScaleProvider.php文件,因为我们已将AwsAutoscale绑定在AutoScalingClientProvider.php上。

如果要通过外观访问AwsAutoscale,则需要为此创建外观类。我们说我们把它放在App\Facades\AutoscaleFacade.php上:

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class AutoscaleFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
        // Return the key we use on service provider to bind AwsAutoclass instance
        return 'autoscale';
    }
}

接下来,我们需要在config\app.php

上注册服务提供者和外观类
<?php

return [
    ...
    'providers' => [
        ...
        App\Providers\AutoScalingClientProvider::class,
    ],
    'aliases' => [
        ...
        'Autoscale' => App\Facades\AutoscaleFacade::class,
    ],
];

现在,您可以使用已注册的别名轻松访问AwsAutoscale实例,如下所示:

Route::get('/foo', function () {
    // Access it with the Autoscale facade class not AwsAutoscale
    dd(\Autoscale::groupStats());
});

希望这会给你一些想法。