eclipsegc/plugins

这个库提供了一套工具,旨在简化对“类似”对象的发现,将这些对象组装到通用字典中,并简化字典中对象的公共工厂模式。

0.1.7 2017-01-20 16:13 UTC

This package is auto-updated.

Last update: 2024-08-29 03:31:44 UTC


README

Build Status Code Climate Test Coverage

什么是插件?

这个库提供了一套工具,旨在

  • 简化“类似”对象的发现
  • 将这些对象组装到通用字典中
  • 简化字典中对象的公共工厂模式

插件库旨在为开发者提供一个简单的模式,允许他们创建自己的可插拔系统。这可以简单到在运行时从库中选择单个插件,或者从库中执行多个插件以执行确定可见性或构建页面组件等操作。

历史与使命

插件系统最初是在2011-2012年与Drupal 8的早期开发一起开发的。尽管Drupal 8于2015年底发布,但插件系统在Drupal 8发布前多年就开始开发,这段代码旨在向整个PHP社区提供插件系统,同时修复Drupal 8版本中许多不完善的地方。我们希望这项工作最终能被整合到Drupal的未来版本中,同时可以在PHP社区中得到更广泛的应用。

用法

每个插件字典必须记录其

  • 插件类型
  • 发现
  • 工厂类
  • 工厂解析器

这些属性共同定义了单个插件字典。最容易的入门方法是构建自己的字典类并使用提供的PluginDictionaryTrait。一个简单的例子可能如下所示

use \EclipseGc\Plugin\Dictionary\PluginDictionaryInterface;
use \EclipseGc\Plugin\Traits\PluginDictionaryTrait;

class MyDictionary implements PluginDictionaryInterface {
  use PluginDictionaryTrait;

  public function __construct(\Traversable $namespaces) {
    $this->discovery = new SomeDiscoveryClass();
    $this->factoryResolver = new SomeFactoryResolver();
    $this->factoryClass = 'My\Default\Factory';
    $this->pluginType = 'myType';
  }

}

插件类型

插件类型是一个简单的字符串,仅用于文档目的。它允许开发人员询问字典类正在处理哪种插件类型。

理解发现

发现是插件系统最基本的部分之一。构建实现接口的类是很好的,但如果应用程序无法找到和执行它们,那就没有意义。插件系统主要作为一个工具,用于查找“类似”接口的类并将它们提供给执行。它通过以下方式实现

  • 公开和记录用于交换子系统内的类
  • 提供一种或多种模式,通过这些模式可以在子系统中逻辑上找到打算使用的类。
  • 提供实例化这些类的方法。

此过程中最关键的部分是用于逻辑上定位相同接口的类的模式。整个系统完全是可插拔的,但为了简单起见,您可以认为发现是任何中央工具可以找到的文档,并从中加载其中一个已记录的类。例如,您可以想象一个神奇的PHP可调用对象,它返回一个插件定义数组或YAML,这些可以解释为插件定义。一种这样的发现解决方案已经存在,它利用了Doctrine的类 注释

发现(Discovery)旨在为开发者提供一个自文档化的机制,以便在整个可用的命名空间中查找新的插件。使用上面的注释示例,要被找到,新的插件必须存在于预期的目录结构中,实现特定的接口,并带有预期的注解类。你可以在其GitHub页面上了解更多关于该特定发现机制的信息。

要执行此类发现调用,插件系统需要每个命名空间及其对应的目录。对于基于Composer的自动加载,插件系统提供了一个静态方法,可以执行必要的操作。只需将自动加载器传递给Namespaces::extractNamespaces()方法。上面的代码文档中看到的可遍历(Traversable)对象就是结果。

工厂类

在插件字典中记录的工厂类是一个回退工厂,用于实例化任何插件。这意味着插件类型的最基本期望应该封装在默认工厂类的期望中。

工厂解析器

工厂解析器的任务是按需实例化工厂类(包括默认工厂)。由于每个插件在实例化时可能有根本不同的需求,因此解析器允许插件单独记录自己的工厂,以便在实例化时有特殊需求。

工厂解析器旨在减少依赖注入问题。允许单次使用的工厂类与单个插件配对,可以防止插件类与一组依赖项紧密耦合。所使用的工厂类带有注解,注解可以在运行时或缓存之前更改。静态工厂方法(Drupal 8用于解决此类基本问题的机制)不能。

如果你正在使用依赖注入容器或类似的控制反转机制,那么你的工厂解析器可能会成为那里的服务,并将整个容器传递给它。这使它们能够在实例化其工厂时满足任何插件的依赖项。在Drupal 8的术语中,这个插件系统实际上将静态工厂方法从插件类本身移动出去,并允许在定制的工厂类上发生相同的代码流,以防止将插件紧密耦合到服务中。