Symfony DI: Uncaught ArgumentCountError: слишком мало аргументов для функции App :: __ construct (), 0 передано в index.php в строке 28 и ожидается ровно 1

Я пытаюсь реализовать контейнер внедрения зависимости Symfonys.

У меня установлено 2 контейнера, один для базы данных и один для пользователя системы.

а я пользуюсьaddArgument()«к обоим App класс и SystemUser класс, подталкивая к App класс SystemUser объект, и для SystemUser класс Database объект.

index.php:

require_once 'vendor/autoload.php';

use TestingDI\App;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');

$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));

$containerBuilder->register('app', '\TestingDI\App')
->addArgument(new Reference('system.user'));


$database       = $containerBuilder->get('database');
$systemUser     = $containerBuilder->get('system.user');
$app            = $containerBuilder->get('app');

# Initialize App class
$app = new App();

app.php:

<?php

namespace TestingDI;

use TestingDI\SystemUser;


class App {

public $systemUser;

public function __construct(SystemUser $systemUser)
{
var_dump($systemUser);
}
}

Я вижу мой результат var_dump с объектом, но продолжаю получать эту ошибку:

Неустранимая ошибка PHP: Uncaught ArgumentCountError: слишком мало аргументов для функции TestingDI \ App :: __ construct (), 0 передано в /www/potato/symfony-di/index.php в строке 28 и ровно 1 ожидается в / www / potato / symfony -ди / testingdi / app.php: 12

Трассировки стека:

0 /www/potato/symfony-di/index.php(28): TestingDI \ App -> __ construct ()

1 {главная}
добавлено в /www/potato/symfony-di/testingdi/App.php в строке 12

Это мои другие занятия:

SystemUser.php

<?php
namespace TestingDI;

use TestingDI\Database;

class SystemUser {

public $db;

public function __construct( Database $database )
{
$this->db = $database;
}
}

database.php

<?php
namespace TestingDI;

class Database {

public function __construct()
{

}
}

-1

Решение

Кажется, что существует неправильное представление о том, что такое внедрение зависимостей и как его использовать.

Поскольку вы используете контейнер зависимостей для создания различных частей вашего приложения, вы должны получать эти объекты из контейнера, не создавать их непосредственно.

И, если вы собираетесь создавать их экземпляры напрямую (например, new App()Вы должны соблюдать правила обычного языка. В этом случае подпись конструктора:

public function __construct(SystemUser $systemUser)

Если вы вызываете конструктор, не передавая ему объект SystemUser класс, он потерпит неудачу, точно так же, как любой другой метод / функция потерпит неудачу, если вы вызовете его способом, который не соответствует его сигнатуре.

К тому времени, как ты это сделал

$app            = $containerBuilder->get('app');

Ваше приложение уже «инициализировано», и вам не нужно было звонить new совсем.

Делая это:

$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');

$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));

$containerBuilder->register('app', '\TestingDI\App')
->addArgument(new Reference('system.user'));


$database       = $containerBuilder->get('database');
$systemUser     = $containerBuilder->get('system.user');
$app            = $containerBuilder->get('app');

Вы делали эквивалент:

$database   = new Database();
$systemUser = new SystemUser($database);
$app        = new App($systemUser);

Только вы позволяли контейнеру DI делать всю работу за вас. Что, конечно, учитывая, как подробный Ваше определение контейнера кажется бессмысленным.

Но вы можете позволить силе автоматическое связывание сделайте большую часть тяжелой работы за вас и сделайте следующее:

$container = new ContainerBuilder();
$container->autowire( Database::class );
$container->autowire( SystemUser::class );
$container->autowire( App::class )
->setPublic( true );

$container->compile();

// this will get you an application instance with all the dependencies
// resolved and injected in the class.
$app = $container->get( App::class );

Теперь я заметил, что у вас уже была похожая проблема, пока пробуя другую библиотеку DI, и теперь я понимаю, что вся проблема заключается в простом непонимании того, с какой проблемой работает контейнер DI

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]