2.8 KiB
2.8 KiB
依赖注入
目录
src/ 类的标准 DI 样板
依赖项通过带有 @internal 注解的 final init 方法注入(前后留空行)。
示例:
namespace Automattic\WooCommerce\Internal\Admin;
use Automattic\WooCommerce\Internal\Logging\Logger;
use Automattic\WooCommerce\Internal\DataStore\OrderDataStore;
class OrderProcessor {
private Logger $logger;
private OrderDataStore $data_store;
/**
* 使用依赖项初始化订单处理器。
*
* @internal
*
* @param Logger $logger 日志记录器实例。
* @param OrderDataStore $data_store 订单数据存储。
*/
final public function init( Logger $logger, OrderDataStore $data_store ) {
$this->logger = $logger;
$this->data_store = $data_store;
}
public function process( int $order_id ) {
$this->logger->log( "Processing order {$order_id}" );
// ...
}
}
初始化设置钩子的类
在 includes/class-woocommerce.php 的 init_hooks() 中添加:
- 使用
$container->get( ClassName::class ); - 添加到“这些类在实例化时设置钩子”部分的末尾
includes/class-woocommerce.php 中的示例:
private function init_hooks() {
// ... 现有代码 ...
// 这些类在实例化时设置钩子
$container->get( SomeExistingClass::class );
$container->get( AnotherExistingClass::class );
$container->get( YourNewClass::class ); // 在此处添加你的新类
}
使用容器获取实例
当需要在代码的其他地方从容器获取类的实例时:
use Automattic\WooCommerce\Internal\Utils\DataParser;
// 从容器获取实例
$parser = wc_get_container()->get( DataParser::class );
单例行为
重要: 容器总是检索给定类的相同实例(单例模式)。
当需要不同的实例时(且仅在此情况下),使用 new 或该类的适当工厂方法(如果可用)。
示例:
// 每次都是相同的实例 - 使用容器
$logger = wc_get_container()->get( Logger::class );
$same_logger = wc_get_container()->get( Logger::class ); // 与上面相同的实例
// 需要不同的实例 - 使用 new 或工厂
$order1 = new WC_Order( 123 );
$order2 = new WC_Order( 456 ); // 不同的实例
// 使用可用的工厂方法
$product = wc_get_product( 789 ); // 工厂方法
为什么使用依赖注入?
- 易于在测试中进行模拟
- 无需更改代码即可交换依赖项
- 签名中明确的依赖关系