dsbj66959 2019-02-18 18:15
浏览 125
已采纳

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

I'm trying to create ServiceProvider for duplicated code in my Laravel application. My solution throws an exception:

Illuminate \ Contracts \ Container \ BindingResolutionException:

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

I have a custom abstract controller where I have a simple singleton function:

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)
            );
        });
(...)
}

This singleton is used in a concrete controller named CreateAccount:

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

I want to create 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];
    }
}

And I add this service to app.php:

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

I know the Laravel tries to resolve dependencies for this service but I don't know how to write this code to resolve primitives in a controller.

In other hand, this class - GetTranslation - is connected with my views, for example:

<?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')
];

How to run this service provider in controller and in views - but i don't need run ->singleton() method in abstract controller. I think the place for this method is in Provider folder, not in controllers.

  • 写回答

1条回答 默认 最新

  • dpbe81245 2019-02-19 07:44
    关注

    I resolve this problem this way:

    1. Create TranslationInterface - even empty.
    2. Implement this interface in GetTranslation::class like:
    class GetTranslation implements TranslationInterface {}
    
    1. I find all usages of app()->make(GetTranslation::class); and replace them with app()->make(TranslationInterface::class);
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求京东批量付款能替代天诚
  • ¥15 slaris 系统断电后,重新开机后一直自动重启
  • ¥15 51寻迹小车定点寻迹
  • ¥15 谁能帮我看看这拒稿理由啥意思啊阿啊
  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含