istok / container

具有 `call(\Closure $fn): mixed` 方法的 DI / IoC 容器

0.0.5 2022-06-04 13:23 UTC

This package is auto-updated.

Last update: 2024-09-04 18:23:25 UTC


README

composer require istok/container
  • 允许通过 Container::call(\Closure $fn): mixed 方法调用任何 \Closure
  • 允许通过属性自定义解析(用于填充 DTO)
  • 允许参数名绑定:Container::argument(string $name, string $for, \Closure $resolver)
  • 提供实现 PSR-11 的包装器(见 Istok\Container\Psr\StrictContainerIstok\Container\Psr\GreedyContainer

注册方法

// Registration of cachable entry
Container::singletone(string $id, string|\Closure $defitition);

// This entry will not be cached
Container::register(string $id, string|\Closure $defitition);

// parameter $name of $for::__construct() will be resolved by given closure 
Container::argument(string $name, string $for, \Closure $resolver);

$definition 参数将由 Container 解析

检索

// take instance
Container::make(string $id);

/**
 * Call $fn with given arguments, using Container::make() for rest
 * @param array<string, mixed> $args
 */
Container::call(\Closure $fn, $args);

/**
 * Psalm-friendly version, contains actual type check, T should be class or interface, result should be typeof T
 * @template T
 * @param class-string<T> $id
 * @return T
 */
Container::construct(string $id): object;

标识符解析顺序

  • 使用直接注册
  • 使用属性,如果适用
  • 尝试构造

闭包参数解析

  • 应用显式提供的参数
  • 使用 Container::get() 解析其余部分

通过属性解析

如果目标类具有实现 Istok\Container\Resolver 接口的属性,将构造属性实例(通过 Container::get,而不是 ReflectionAttribute::newInstance()),然后返回 Resolver::resolve($targetName, ...$attributeArgs) 的结果作为结果。

服务和模型解析

根据 Matthias Noback 的《对象设计风格指南》(Object Design Style Guide),存在两种类型的对象

两种类型的对象

在应用程序中通常有两种类型的对象

  1. 服务对象,它们执行任务或返回信息。
  2. 持有某些数据,并可选择公开一些用于操作或检索这些数据的行为的对象。

第一种类型有一个已知的名称,即 Service,另一种我称为 Model(我必须这样称呼)。
虽然 Services 依赖于其他 ServicesModels,但 Models 仅依赖于其他 Modelsinput

创建此容器的原因之一是希望能够获取从用户输入或配置中填充的具有良好类型的 DTO,作为我的控制器参数。

为了实现这一点,我添加了 Resolver 接口,其实现可以作为 Model 的属性使用。
这允许为解析此类对象添加上下文配置。

因此,Container 本身主要用于解析 Services,而 ModelResolver 用于解析 Models,如请求 DTOs