dreamcat / container
窗口,依赖注解直接赋值
v3.1.0
2020-01-21 06:09 UTC
Requires
- php: >=7.2
- dreamcat/annotation_parser: ^1
- dreamcat/option: ^1
- dreamcat/property_analysis: ^1
- psr/container: ^1.0
Requires (Dev)
- phpunit/phpunit: ^8
Provides
README
介绍
容器,通过注解直接赋值,减少构造函数中的操作
版本更新记录
2.0.0
- ID中支持标明是否重新构建、是否保留实例、指定使用范围的信息
- 注册时可以标明指定范围、是否保留实例的信息
- 注册时可以只传入工厂类名,在需要创建实例时再创建工厂
- 注册时可以添加对象属性赋值(如果注册时标明的是工厂,则是对工厂对象赋值)
- 增加范围容器,实例范围只在范围容器中出现
- 增加克隆魔术方法,克隆容器时不再复制已创建的实例,只保留配置信息
安装教程
composer require dreamcat/container
容器使用说明
创建容器,注入相应工厂方法、别名、实例
<?php use DreamCat\Container\AnnotationDealer; use DreamCat\Container\HelperInfo\RegeditInfo; use DreamCat\Container\HelperInfo\ScopeRegeditInfo; // 容器常用方法说明,PSR 标准接口不列出 class Container implements ContainerInterface { /** * 注册创建模式 * @param string $id 实体标识 * @param RegeditInfo $info 注册信息 * @param bool $overwrite 是否覆盖原有设定 * @return static 容器本身 */ public function regedit(string $id, RegeditInfo $info, bool $overwrite = true): Container { return $this; } /** * 直接注册一个实体对象 * @param string $id 实体标识 * @param mixed $object 实体对象 * @return Container 容器本身 */ public function regeditInstance(string $id, $object): Container { return $this; } /** * 注册自定义注解处理器 * @param string $annotation 注解名称 * @param AnnotationDealer $annotationDealer 处理器 * @return Container 容器本身 */ public function regeditAnnotation(string $annotation, AnnotationDealer $annotationDealer): Container { return $this; } } // 带范围功能的容器 class ScopeContainer extends Container { /** * ScopeContainer constructor. * @param Container $globalContainer 全局容器 */ public function __construct(Container $globalContainer) {} /** * 注册创建模式 * @param string $id 实体标识 * @param ScopeRegeditInfo $info 注册信息 * @param bool $overwrite 是否覆盖原有设定 * @return static 容器本身 */ public function regedit( string $id, ScopeRegeditInfo $info, bool $overwrite = true ): ScopeContainer { return $this; } }
在需要的时候调用容器的
get
方法即可获取对象,会将构造函数中参数通过容器获取并传入,逻辑如下:- 如果函数声明中有默认参数直接使用默认参数
- 如果参数无类型声明,传入
null
- 如果参数类型是内置类型,传入默认值
int
、float
=0
string
=""
array
=[]
bool
=false
callable
=function () {}
- 以参数类名为对象标识,在容器中获取对象
构造函数创建对象完成之后,遍历所有的属性(包括继承的),依据注解规则注入参数
- 所有注册类函数一定要先期调用,等调用过
get
方法之后,注册函数不一定生效
get($id)
方法的 id
结构说明
[crg|]id[::arg]
其中方括号的部分都是可选的
前缀的 c
r
q
顺序没有限制
c
存在此字符表示只做创建,无需在容器中保留r
存在此字符表示不论原先是否有创建过,都是直接重新创建g
仅在ScopeContainer
中生效,表示在全局容器中创建
后缀的子参数 arg
仅在工厂模式下有意义,用于 create
方法的第二参数
注解说明
目前只支持注解加在属性上,不管是 public
、protected
、private
都是可以的,但是 static
属性是无效的,无法注入
注意 所有不通过容器创建的对象,注解都是不生效的
- 加入注解
Autowire
且注解无参数声明,则类型依赖var
注解。不支持内置类型(比如int
),这些类型直接使用默认值即可。 注意类名如果不是以\
开始,则会首先在当前文件的use
语句查找,然后在当前名空间查找,最后尝试全局 - 加入注解
Autowire
且注解后跟一个名称,则使用相应名称做为实体标识到容器中获取对象 - 如果加入自定义注解处理器,则将注解后面的字符串以空格隔开做为参数传入对应处理器,将返回值做为值注入属性
- 多个预期生效的注入注解,可能发生不可预期的情况
- 属性注入是不会检查是否已设定默认值,如果注入生效,会覆盖默认值
注解示例
<?php
class AnnotationDemo
{
/**
* @Autowire
* @var Class1 $value1
* @note 从容器中获取一个 Class1 对象注入
*/
private $value1;
/**
* @Authwire db
* @var Class2 $value2
* @note 从容器中获取一个标识为 db 的对象注入
*/
private $value2;
/**
* @Config db.username
* @var string $value3
* @note 调用 Config 注解的处理器
*/
private $value3;
}
todo list
- 解决close事件可能被多次调用的问题
- 解决trait里声明的属性无法解析类型的问题