Ric*_*hez 2 php dependency-injection symfony symfony-dependency-injection
我正在尝试实现 Symfonys 依赖注入容器。
我设置了 2 个容器,一个用于数据库,一个用于系统用户。
和我使用addArgument()的这两个App阶级和SystemUser阶级,推到App类SystemUser对象,并为SystemUser类Database对象。
索引.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();
Run Code Online (Sandbox Code Playgroud)
应用程序.php:
<?php
namespace TestingDI;
use TestingDI\SystemUser;
class App {
public $systemUser;
public function __construct(SystemUser $systemUser)
{
var_dump($systemUser);
}
}
Run Code Online (Sandbox Code Playgroud)
我确实看到了带有对象的 var_dump 结果,但不断收到此错误:
PHP 致命错误:未捕获的 ArgumentCountError:函数 TestingDI\App::__construct() 的参数太少,0 在第 28 行传入 /www/potato/symfony-di/index.php,而在 /www/potato/symfony 中预期正好为 1 -di/testingdi/App.php:12
堆栈跟踪:
0 /www/potato/symfony-di/index.php(28): TestingDI\App->__construct()
1 {main} 在第 12 行的 /www/potato/symfony-di/testingdi/App.php 中抛出
这些是我的其他课程:
系统用户.php
<?php
namespace TestingDI;
use TestingDI\Database;
class SystemUser {
public $db;
public function __construct( Database $database )
{
$this->db = $database;
}
}
Run Code Online (Sandbox Code Playgroud)
数据库.php
<?php
namespace TestingDI;
class Database {
public function __construct()
{
}
}
Run Code Online (Sandbox Code Playgroud)
关于什么是依赖注入以及如何使用它,似乎存在一个基本的误解。
由于您使用依赖容器来构建应用程序的不同部分,因此您应该从容器中获取这些对象,而不是直接实例化它们。
而且,如果您要直接实例化它们(例如new App()),您需要尊重常规语言规则。在这种情况下,构造函数的签名:
public function __construct(SystemUser $systemUser)
Run Code Online (Sandbox Code Playgroud)
如果您调用构造函数而不将SystemUser类的对象传递给它,它将失败,同样,如果您以不符合其签名的方式调用它,任何其他方法/函数都会失败。
当你这样做的时候
$app = $containerBuilder->get('app');
Run Code Online (Sandbox Code Playgroud)
您的应用程序已经“初始化”,您根本不需要调用new。
通过做这个:
$app = $containerBuilder->get('app');
Run Code Online (Sandbox Code Playgroud)
你所做的相当于:
$database = new Database();
$systemUser = new SystemUser($database);
$app = new App($systemUser);
Run Code Online (Sandbox Code Playgroud)
只有您让 DI 容器为您完成工作。当然,考虑到您的容器定义是多么冗长,这似乎毫无意义。
但是您可以让自动装配的力量为您完成大部分繁重的工作,并执行以下操作:
$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');
Run Code Online (Sandbox Code Playgroud)
我现在注意到您在尝试不同的 DI 库时已经遇到了类似的问题,现在我意识到整个问题都围绕着对 DI 容器处理什么问题的简单误解。
| 归档时间: |
|
| 查看次数: |
5200 次 |
| 最近记录: |