nimble/carton

一个简单的PSR-11容器实现,提供基于反射的自动装配。

2.0.1 2024-09-21 17:33 UTC

This package is auto-updated.

Last update: 2024-09-21 17:40:07 UTC


README

Latest Stable Version GitHub Workflow Status Codecov branch License

简单的PSR-11容器实现。

特性

  • PSR-11兼容
  • 单例和工厂构建器
  • 服务提供者
  • 嵌套容器支持
  • 基于反射的自动装配

安装

composer require nimbly/carton

获取容器

实例化容器

您可以为容器创建一个新实例。

$container = new Container;

单例实例

或使用容器单例的 getInstance 方法。

$container = Container::getInstance();

基本用法

设置实例

最基本的用法是将实例直接赋给容器本身。

$container->set(SomeInterface::class, new SomeClass);

当然,您不需要 分配 对象,可以是任何您喜欢的。

$container->set("timezone", "UTC");

检索值

通过键从容器中获取值。

$someClass = $container->get(SomeClass::class);

注意:检索不存在的值将抛出 NotFoundException

检查实例

您可以检查容器中注册的项目是否存在。

if( $container->has(SomeClass::class) ){
	echo "Container has SomeClass::class.";
}

高级用法

单例构建器

单例构建器将确保从容器检索时始终返回单个实例。

它还有比 set 方法额外的优势,即它通过延迟实例化类来创建实例。也就是说,只有在实际需要时才会创建。

$container->singleton(
	SomeClass::class,
	function(Container $container): void {
		return new SomeClass(
			$container->get("SomeDependency")
		);
	}
);

工厂构建器

工厂构建器每次从容器检索时都会创建新实例。

$container->factory(
	SomeClass::class,
	function(Container $container): void {
		return new SomeClass(
			$container->get("SomeDependency")
		);
	}
);

自动装配

您可以使用 make 方法自动为您创建实例 - 该方法将尝试从容器本身拉取依赖项,或者在找不到的情况下递归尝试 make 它们。

class Foo
{
	public function __construct(
        protected DateTime $date)
	{
	}
}

class Bar
{
	public function __construct(
        protected Foo $foo)
	{
	}
}

$bar = $container->make(Bar::class);

实例方法上的依赖注入

调用实例方法非常简单 - Carton 在调用实例方法时会尝试为您自动解决依赖项(自动装配)。

class BooksController
{
	public function get(ServerRequestInterface $request, string $isbn): Response
	{
		return new Response(
			Books::find($isbn)
		);
	}
}

$container->set(ServerRequestInterface::class, $serverRequest);
$response = $container->call([BooksController::class, "get"], ["isbn" => "123123"]);

添加附加容器

您可以通过调用 addContainer 方法使用附加的PSR-11兼容容器实例扩展Carton。当Carton尝试解决项目时,它将始终首先尝试本地解决,如果找不到,将遍历您提供的任何附加容器。

例如,如果您有一个实现了 ContainerInterface(PSR-11)的配置管理器,您可以将它添加到Carton中。

$container->addContainer(
	new Config([
		new FileLoader(__DIR__ . "/config")
	])
);

$container->get("database.connections");

现在您可以通过容器实例检索您的配置数据。

服务提供者

服务提供者允许您通过一组类组织您的应用程序依赖项。

创建实现 ServiceProviderInterface 的服务类。

class MyServiceProvider implements ServiceProviderInterface
{
	public function register(Container $container): void
	{
		$container->singleton(
			MyService::class,
			function(Container $container): void {
				return new MyService(
					$container->get(SomeDependency::class)
				);
			}
		);
	}
}

然后注册您的服务提供者到容器。

$container->register(new MyServiceProvider);

您还可以一次性注册多个服务,并按类名注册服务。

// Register group of services at once.
$container->register([
	new MyServiceProvider,
	new MyOtherServiceProvider
]);

// Register services by class name.
$container->register(MyServiceProvider::class);

// Register group of services by class name.
$container->register([
	MyServiceProvider::class,
	MyOtherServiceProvider::class
]);