decodelabs / archetype
简单的命名库加载器
Requires
- php: ^8.1
- decodelabs/exceptional: ^0.4
- decodelabs/glitch-support: ^0.4
- decodelabs/veneer: ^0.11.1
Requires (Dev)
- decodelabs/phpstan-decodelabs: ^0.6.6
This package is auto-updated.
Last update: 2024-09-04 20:51:18 UTC
README
PHP简单的命名库加载器
Archetype提供了一个通用的前端,用于通过可扩展的插件架构解析具有命名接口的实现类。
在DecodeLabs博客上获取新闻和更新。
安装
通过Composer安装
composer require decodelabs/archetype
用法
导入
Archetype使用Veneer在DecodeLabs\Archetype
下提供一个统一的接口。您可以通过这个静态接口访问所有主要功能,而不会影响测试和依赖注入。
功能
当设计需要根据命名约定加载任意扩展类的插件库时,请使用Archetype。
通过将名称映射到可扩展和可定制的解析器结构中的类,Archetype允许快速、可靠地创建松散耦合的插件生态系统。
示例
// Main library namespace My\Library { use DecodeLabs\Archetype; interface Thing {} class Factory { public static function loadThing(string $name): Thing { // Resolve name to class for Thing interface $class = Archetype::resolve(Thing::class, $name); return new $class(); } } } // Thing implementations namespace My\Library\Thing { use My\Library\Thing; class Box implements Thing {} class Potato implements Thing {} class Dog implements Thing {} } // Calling code namespace My\App { use My\Library\Factory; $box = Factory::loadthing('Box'); $potato = Factory::loadThing('Potato'); $dog = Factory::loadThing('Dog'); }
解析器
Archetype使用Resolvers
的层次结构将名称转换为类。默认情况下,Handler
将回退到Resolver\Generic
实例,该实例只需在关联接口的命名空间中定位具有名称的类。
在上面的示例中,My\Library\Thing
的实现可以在My\Library\Thing\*
中找到。
自定义解析器
然而,Resolver\Archetype
实现还会自动在同一位置查找自定义Resolver
类,该位置与目标接口相同,名称为<Interface>Archetype
。
以下示例将替换默认功能,并导致Archetype在查找Thing
实现时查找不同的位置。
namespace My\Library { use DecodeLabs\Archetype\Resolver; class ThingArchetype implements Resolver { public function getInterface(): string { return Thing::class; } public function getPriority(): int { return 10; } public function resolve(string $name): ?string { return 'Some\\Other\\Namespace\\'.$name; } } }
多个解析器
多个Resolver
实例可以针对单个接口堆叠,根据它们请求的优先级按顺序调用,第一个返回非空类名的解析器获胜。
可以通过以下方式加载替代Resolvers
:
use DecodeLabs\Archetype; use My\Library\Resolver\Alternative as AlternativeResolver; Archetype::register(new AlternativeResolver());
文件查找
Resolvers
还实现了Finder
接口,可以定义根据提供的名称在目标接口定义的空间内查找文件路径的方法。
当根接口定义的空间可能包含除PHP代码以外的资源时,这很有用。
具体实现将决定如何将名称映射到文件路径(没有预构建的默认Finder
类)。
示例
namespace My\Library { use DecodeLabs\Archetype\Finder; class ThingArchetype implements Finder { public function getInterface(): string { return Thing::class; } public function getPriority(): int { return 10; } public function resolve(string $name): ?string { return 'Some\\Other\\Namespace\\'.$name; } public function findFile(string $name): ?string { return './some/other/namespace/'.$name.'.jpg'; } } } namespace My\App { use DecodeLabs\Archetype; use My\Library\Thing; $boxImagePath = Archetype::findFile(Thing::class, 'box'); }
许可
Archetype采用MIT许可。有关完整的许可文本,请参阅LICENSE。