簡體   English   中英

Laravel:在構建時無法實例化目標

[英]Laravel: Target is not instantiable while building

抱歉,如果該問題重復,但是我在StackOverflow中閱讀了很多相關問題,但沒有一個解決了我的問題:

我創建了一個有效的Artisan命令並在其中注入了Kafka客戶端服務作為第一個參數,並注入了一個具體類BudgetsTransformer作為第二個參數

class ConsumeBudgetsCommand extends Command {
    public function __construct(FKafka $kafkaClient, BudgetsTransformer $transformer)
    {
        $this->kafkaClient = $kafkaClient;
        $this->transformer = $transformer;

        parent::__construct();
    }
}

AppServiceProvider類看起來像:

class AppServiceProvider extends ServiceProvider
{

    public function register()
    {
        $this->app->bind('kafka.client', function ($app) {
            return new \Weq\FKafka\FKafka();
        });

        $this->app->bind('budget.transformer', function ($app) {
            return new BudgetsTransformer();
        });

    }

    public function boot()
    {
        $this->app->bind('consume:budgets', function ($app) {
            return new ConsumeBudgetsCommand($app['kafka.client'], $app['budget.transformer']);
        });

        $this->commands('consume:budgets');
    }
}

到目前為止,一切工作正常……然后,我決定創建一個由BudgedTransformer實現的TransformerInterface (其他將來的Transformers也會實現):

class BudgetsTransformer implements TransformerInterface
{
 // ...
}

我在命令中更改了簽名以注入接口而不是具體的類:

class ConsumeBudgetsCommand extends Command {
    public function __construct(FKafka $kafkaClient, TransformerInterface $transformer)
    {
        $this->kafkaClient = $kafkaClient;
        $this->transformer = $transformer;

        parent::__construct();
    }
}

但是當我嘗試運行一些artisan命令時出現以下問題

在Container.php行933中:在構建[App \\ Console \\ Commands \\ ConsumeBudgetsCommand]時,無法實例化目標[App \\ Transformers \\ TransformerInterface]。

我以前運行以下工匠命令運行此問題,以防萬一... cache:clearclear-compiledoptimize等,但是沒有運氣

我做錯了什么? 我是否應該以與傳遞和接口(而不是具體的類)不同的方式綁定BudgetTransformer

在此先感謝您的幫助

更新資料

正如@davit建議的那樣,我添加了

$this->app->bind(TransformerInterface::class, BudgetsTransformer::class);

在AppServiceProvider :: register()中,我刪除了

$this->app->bind('budget.transformer', function ($app) {
        return new BudgetsTransformer();
});

在那里,然后我在AppServiceProvider :: boot()中更新命令綁定:

$this->app->bind('consume:budgets', function ($app) {
        return new ConsumeBudgetsCommand($app['kafka.client'], $app[TransformerInterface::class]);
});

但是仍然無法正常工作,無論如何,這種方法(即使CostTransformer )也無法解決問題,因為當我想添加另一個不同的轉換器實現時,假設實現TransformerInterface BudgetTransformer總是會注入BudgetTransformer 因此,閱讀鏈接中的文檔后,我發現Contextual Binding可能是解決方案,因此我對以下內容表示懷疑:

$this->app
        ->when(ConsumeBudgetsCommand::class)
        ->needs(TransformerInterface::class)
        ->give(function ($app) {
            return new BudgetsTransformer();
        });

因此,通過這種方式,我將能夠通過注入接口將轉換器的不同實現注入不同的命令。 但仍然無法正常工作。

有人可以告訴我如何精確聲明命令綁定

$this->app->bind('consume:budgets', function ($app) {
        return new ConsumeBudgetsCommand($app['kafka.client'], ???);
    });

使用Contextual binding

對於綁定接口,必須使用此結構https://laravel.com/docs/5.5/container#binding-interfaces-to-implementations

$this->app->bind(TransformerInterface::class, BudgetsTransformer::class);

$this->app->bind('consume:budgets', function ($app) {
    return new ConsumeBudgetsCommand($app['kafka.client'], $app->make(TransformerInterface::class));
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM