php依赖注入容器功能代码教程文档(AI创作)
1个月前
这个依赖注入容器基本实现了功能如下:容器(Container)- 服务(Service)- 绑定(Binding)- 单例(Singleton)- 上下文绑定- 延迟加载
单文件完整版本
# Dream Kernel Vessel 容器使用文档
dream\kernel\vessel\Container 是一个轻量级依赖注入容器,用于管理类的实例化、依赖解析和服务注册,支持单例、上下文绑定、延迟加载等功能。以下是详细使用指南:
所有类位于 dream\kernel\vessel 命名空间下,使用前需通过 use 引入:
use dream\kernel\vessel\Container;$container = new Container();将服务标识符与具体实现绑定,每次解析都会创建新实例(非单例)。
// 绑定类名(默认使用类名作为标识符)
$container->bind('logger', \app\services\Logger::class);
// 绑定闭包(更灵活的实例化逻辑)
$container->bind('cache', function ($container) {
return new \app\services\Cache($container->get('config'));
});
// 简化绑定(标识符与类名相同时)
$container->bind(\app\services\Db::class);单例服务只会实例化一次,后续调用 get() 会返回同一个实例。
// 绑定单例类
$container->singleton('config', \app\Config::class);
// 绑定单例闭包
$container->singleton('db', function ($container) {
return new \PDO(...);
});为服务添加标签,便于批量获取同一类别的服务。
// 为服务添加标签
$container->tag(['logger', 'cache'], 'services');
$container->tag('db', 'services');
// 通过标签获取所有服务
$services = $container->getByTag('services');
// $services 包含 'logger'、'cache'、'db' 三个服务实例通过服务标识符从容器中获取实例。
// 解析服务
$logger = $container->get('logger');
$db = $container->get(\app\services\Db::class);if ($container->has('cache')) {
// 服务已注册或实例化
}容器会自动解析类的构造函数依赖,无需手动传递参数。
class UserService {
private $db;
private $logger;
// 构造函数依赖 Db 和 Logger
public function __construct(\app\services\Db $db, \app\services\Logger $logger) {
$this->db = $db;
$this->logger = $logger;
}
}
// 注册依赖的服务
$container->bind(\app\services\Db::class);
$container->bind(\app\services\Logger::class);
// 解析 UserService 时,容器会自动注入 Db 和 Logger
$userService = $container->get(UserService::class);为特定类提供专属的依赖实现(场景:同一接口在不同类中需要不同实现)。
// 定义接口和实现
interface PaymentInterface {
public function pay();
}
class Alipay implements PaymentInterface {
public function pay() { /* 支付宝支付逻辑 */ }
}
class WechatPay implements PaymentInterface {
public function pay() { /* 微信支付逻辑 */ }
}
// 订单服务依赖 PaymentInterface
class OrderService {
private $payment;
public function __construct(PaymentInterface $payment) {
$this->payment = $payment;
}
}
// 购物车服务也依赖 PaymentInterface
class CartService {
private $payment;
public function __construct(PaymentInterface $payment) {
$this->payment = $payment;
}
}
// 上下文绑定:为 OrderService 绑定 Alipay,为 CartService 绑定 WechatPay
$container
->when(OrderService::class)
->needs(PaymentInterface::class)
->give(Alipay::class);
$container
->when(CartService::class)
->needs(PaymentInterface::class)
->give(WechatPay::class);
// 解析时会自动注入对应的实现
$orderService = $container->get(OrderService::class); // 注入 Alipay
$cartService = $container->get(CartService::class); // 注入 WechatPay通过代理类延迟服务实例化,直到首次调用方法时才创建对象(适用于资源密集型服务)。
// 绑定延迟加载的服务
$container->bind('heavyService', new \dream\kernel\vessel\LazyProxy(\app\services\HeavyService::class));
// 此时并未实例化 HeavyService
$proxy = $container->get('heavyService');
// 首次调用方法时,才会实例化 HeavyService
$proxy->doSomething(); // 触发实例化并调用方法容器在解析服务失败时会抛出 Exception,包含详细错误信息:
try {
$container->get('undefinedService');
} catch (\Exception $e) {
echo $e->getMessage(); // 输出:Error resolving [undefinedService]: Service [undefinedService] not found.
}use dream\kernel\vessel\Container;
// 初始化容器
$container = new Container();
// 绑定服务
$container->singleton('config', function () {
return new \app\Config(['db_host' => 'localhost']);
});
$container->bind('db', function ($c) {
return new \app\Db($c->get('config'));
});
// 上下文绑定
$container
->when(\app\services\AdminLogger::class)
->needs(\app\services\Logger::class)
->give(\app\services\FileLogger::class);
// 解析服务
$db = $container->get('db');
$adminLogger = $container->get(\app\services\AdminLogger::class);