woocommerce/.ai/skills/woocommerce-backend-dev/zh-cn/dependency-injection.md
2026-04-15 10:18:01 +08:00

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.phpinit_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 );  // 工厂方法

为什么使用依赖注入?

  • 易于在测试中进行模拟
  • 无需更改代码即可交换依赖项
  • 签名中明确的依赖关系