semperton/container

基于反射的自动装配的动态PSR-11依赖注入容器。

2.3.0 2022-08-09 13:18 UTC

This package is auto-updated.

Last update: 2024-09-09 18:51:36 UTC


README

Semperton

Semperton Container

一个轻量级的PSR-11依赖注入容器
基于反射的自动装配。

安装

只需使用Composer

composer require semperton/container

Container需要PHP 7.2+

接口

new Container(iterable $definitions = [], bool $autowire = true)

容器提供四个公开方法

with(string $id, $entry): Container // add a container entry
get(string $id) // get entry (PSR-11)
has(string $id): bool // has entry (PSR-11)
create(string $id, array $params = []); // create a class with optional constructor substitution args
entries(): array // list all container entries

用法

只要类不需要任何特殊配置(自动装配),就可以自动解析类。

use Semperton\Container\Container;

class World
{
	public function __toString()
	{
		return 'World';
	}
}

class Hello
{
	protected $world;
	public function __construct(World $world)
	{
		$this->world = $world;
	}
	public function print()
	{
		echo "Hello {$this->world}";
	}
}

$container = new Container();
$hello = $container->get(Hello::class);
$hello2 = $container->get(Hello::class);

$hello instanceof Hello::class // true
$hello === $hello2 // true
$hello->print(); // 'Hello World'

请注意,容器只创建实例一次。它不作为工厂使用。您应考虑使用工厂模式或使用create()方法。

use Semperton\Container\Container;

class Mail
{
	public function __construct(Config $c, string $to)
	{
	}
}

class MailFactory
{
	public function createMail(string $to)
	{
		return new Mail(new Config(), $to);
	}
}

$mail1 = $container->get(MailFactory::class)->createMail('info@example.com');
$mail2 = $container->create(Mail::class, ['to' =>'info@example.com']);

create()方法将自动解析MailConfig依赖项。

配置

您可以使用定义配置容器。Callables(除了可调用对象)始终被视为工厂,可以(应该)用于启动类实例

use Semperton\Container\Container;

$container = new Container([

	'mail' => 'local@host.local',
	'closure' => static function () { // closures must be wrapped in another closure
		return static function () {
			return 42;
		};
	},
	MailFactory::class => new MailFactory('local@host.local'), // avoid this, instead do
	MailFactory::class => static function (Container $c) { // lazy instantiation with a factory

		$sender = $c->get('mail');
		return new MailFactory($sender);
	}, // or
	// factory params are automatically resolved from the container
	MailFactory::class => static fn (string $mail) => new MailFactory($mail),
	Service::class => static fn (Dependency $dep) => new Service($dep)
]);

$container->get('mail'); // 'local@host.local'
$container->get('closure')(); // 42
$container->get(MailFactory::class); // instance of MailFactory

with()方法也将callables视为工厂。

不可变性

容器创建后即不可变。如果您想在实例化后添加条目,请注意,with()方法始终返回一个新的容器实例

use Semperton\Container\Container;

$container1 = new Container();
$container2 = $container1->with('number', 42);

$container1->has('number'); // false
$container2->has('number'); // true

$container1 === $container2 // false