ServiceProvider с одиночным запросом типов примитивов в методе контроллера DI - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь создать ServiceProvider для дублированного кода в моем приложении Laravel.Мое решение выдает исключение:

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() в абстрактном контроллере.Я думаю, что место для этого метода находится в папке провайдера, а не в контроллерах.

1 Ответ

0 голосов
/ 19 февраля 2019

Я решаю эту проблему следующим образом:

  1. Создать TranslationInterface - даже пусто.
  2. Реализовать этот интерфейс в GetTranslation::class как:
class GetTranslation implements TranslationInterface {}
Я нахожу все употребления app()->make(GetTranslation::class); и заменяю их на app()->make(TranslationInterface::class);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...