具有单例的ServiceProvider要求控制器方法DI中的基元类型

问题描述 投票:0回答:1

我正在尝试为Laravel应用程序中的重复代码创建ServiceProvider。我的解决方案抛出异常:

Illuminate \ Contracts \ Container \ BindingResolutionException:

Unresolvable dependency resolving [Parameter #0 [ <required> string $shortName ]] in class App\Domain\Translation\GetTranslation

我有一个自定义抽象控制器,我有一个简单的单例函数:

namespace App\Http\Controllers\WWW;

class CustomController {
(...)
        app()->singleton(
            GetTranslation::class, function() {
            return new GetTranslation(
                TrimSuffixFromUrl::getShortName(),
                LanguageMap::getLanguageIdByCode(\LaravelLocalization::getCurrentLocale()),
                app()->make(CurrentLanguage::class)
            );
        });
(...)
}

此单例用于名为CreateAccount的具体控制器中:

class CreateAccount extends ControllerWWW
{
    public function index(Request $request, DbInstanceFactory $dbInstance, GetTranslation $translation)
    {
        $getTranslation = $translation; // For simplify this example I remove logic
        // (...)
    }

我想创建ServiceProvider

<?php 
declare(strict_types=1);

namespace App\Providers;

use App\Domain\Domains\Prefix\TrimSuffixFromUrl;
use App\Domain\Language\CurrentLanguage;
use App\Domain\Translation\GetTranslation;
use App\Repository\LanguageMap;
use Illuminate\Support\ServiceProvider;

/**
 * Class TranslatioServiceProvider
 * @package App\Providers
 */
class TranslationServiceProvider extends ServiceProvider
{
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register(): void
    {
        app()->singleton(
            GetTranslation::class, function() {
                return new GetTranslation(
                    TrimSuffixFromUrl::getShortName(),
                    LanguageMap::getLanguageIdByCode(\LaravelLocalization::getCurrentLocale()),
                    app()->make(CurrentLanguage::class)
                );
            }
        );
    }

    /**
     * @return array
     */
    public function provides(): array
    {
        parent::provides();

        return [GetTranslation::class];
    }
}

我将此服务添加到app.php

'providers' => [
    App\Providers\TranslationServiceProvider::class,
]

我知道Laravel尝试解决此服务的依赖关系,但我不知道如何编写此代码来解析控制器中的基元。

另一方面,这个类 - GetTranslation - 与我的观点有关,例如:

<?php
// resources/lang/br/validation.php
declare(strict_types=1);

$translation = app()->make(\App\Domain\Translation\GetTranslation::class);

return [
    'required' => $translation->getTranslationsByKey('tranlation_my_key')
];

如何在控制器和视图中运行此服务提供程序 - 但我不需要在抽象控制器中运行->singleton()方法。我认为这个方法的位置在Provider文件夹中,而不是在控制器中。

php laravel laravel-5 autowired service-provider
1个回答
0
投票

我这样解决这个问题:

  1. 创建TranslationInterface - 甚至是空的。
  2. GetTranslation::class中实现此接口,如:
class GetTranslation implements TranslationInterface {}
  1. 我发现app()->make(GetTranslation::class);的所有用法,并用app()->make(TranslationInterface::class);替换它们
© www.soinside.com 2019 - 2024. All rights reserved.