具有单例的 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 文件夹中,而不是在控制器中。
我这样解决这个问题:
- 创建
TranslationInterface
- 即使是空的。
- 在
GetTranslation::class
中实现此接口,例如:
class GetTranslation implements TranslationInterface {}
- 我找到
app()->make(GetTranslation::class);
的所有用法并将其替换为 app()->make(TranslationInterface::class);
我正在尝试为我的 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 文件夹中,而不是在控制器中。
我这样解决这个问题:
- 创建
TranslationInterface
- 即使是空的。 - 在
GetTranslation::class
中实现此接口,例如:
class GetTranslation implements TranslationInterface {}
- 我找到
app()->make(GetTranslation::class);
的所有用法并将其替换为app()->make(TranslationInterface::class);