具有单例的 ServiceProvider 在控制器方法 DI 中请求原始类型

ServiceProvider with a singleton asking for primitive types in controller method DI

我正在尝试为我的 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 试图解析此服务的依赖关系,但我不知道如何编写此代码来解析控制器中的原语。

另一方面,这个class - 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 文件夹中,而不是在控制器中。

我这样解决这个问题:

  1. 创建 TranslationInterface - 即使是空的。
  2. GetTranslation::class 中实现此接口,例如:
class GetTranslation implements TranslationInterface {}
  1. 我找到 app()->make(GetTranslation::class); 的所有用法并将其替换为 app()->make(TranslationInterface::class);