首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Zend Expressive 3中使用AbstractPluginManager

在Zend Expressive 3中使用AbstractPluginManager
EN

Stack Overflow用户
提问于 2018-04-12 21:42:59
回答 2查看 145关注 0票数 0

我想将一个对象数组注入到我的一个服务中,这些对象实现了一个公共接口。我使用zend servicemanager作为DI容器。我现在已经阅读了相当多的文档,在我看来AbstractPluginManager是一条可行的道路。不过,我还没能让它工作。有没有使用AbstractPluginManager + Zend Expressive 3的例子,我可以看看?

我的最终目标是动态地将实现公共接口的所有注册类注入到我的服务中。

示例:

代码语言:javascript
运行
复制
interface I{}
class A implements I{}
class B implements I{}
class C{}

MyService

代码语言:javascript
运行
复制
__construct(array Iimplementations){...}

$service = $container->get('myservice')

$service has Iimplementations

提前感谢

EN

回答 2

Stack Overflow用户

发布于 2018-04-13 16:55:41

AbstractPluginManager主要用于验证和过滤器插件。您可以创建类,并且在验证时,您可以传递特定的配置,从而使过滤器或验证器可重用。

你要找的可能是一个abstract factory。您只需注册一次工厂,它就可以为您创建一个服务。在您的情况下,使用一组特定的依赖项。

代码语言:javascript
运行
复制
interface I{}
class A implements I{}
class B implements I{}

class MyAbstractFactory implements AbstractFactoryInterface
{
    public function canCreate(ContainerInterface $container, $requestedName)
    {
        return in_array('I', class_implements($requestedName), true);
    }

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        return new $requestedName(
            $container->get(DependencyFoo::class),
            $container->get(DependencyBar::class)
        );
    }
}

// config/autoload/dependencies.global.php
return [
    'dependencies' => [
        'factories' => [
            // ...
        ],

        'abstract_factories' => [
            MyAbstractFactory::class,
        ],
    ],
];

如果每个类的依赖项不同,您也可以疯狂地使用反射来检测依赖项,但是这会增加很多开销。我认为创建独立的工厂更容易,也更易于维护。然后是zend-expressive-tooling,这是一个可以创建工厂、处理程序和中间件的cli工具。

票数 2
EN

Stack Overflow用户

发布于 2018-04-17 00:22:48

代码语言:javascript
运行
复制
/*Getting I concrete implementations via the plugin manager will ensure the implementation of the I interface*/   
class IPluginManager extends AbstractPluginManager
{
   protected $instanceOf = I::class;

   public function getIConcreteImplementations()
   {
       $concreteImpl = [];
       foreach(array_keys($this->factories) as $key)
       {
           $concreteImpl[] = $this->get($key);
       }

       return $concreteImpl;
    }
}
/*IPluginManagerFactory*/
class TransactionSourcePluginManagerFactory
{
  const CONFIG_KEY = 'i-implementations-config-key';

public function __invoke(ContainerInterface $container, $name, array $options = null)
{
    $pluginManager = new IPluginManager($container, $options ?: []);

    // If this is in a zend-mvc application, the ServiceListener will inject
    // merged configuration during bootstrap.
    if ($container->has('ServiceListener')) {
        return $pluginManager;
    }

    // If we do not have a config service, nothing more to do
    if (! $container->has('config')) {
        return $pluginManager;
    }

    $config = $container->get('config');

    // If we do not have validators configuration, nothing more to do
    if (! isset($config[self::CONFIG_KEY]) || ! 
      is_array($config[self::CONFIG_KEY])) {
        return $pluginManager;
    }

    // Wire service configuration for validators
    (new Config($config[self::CONFIG_KEY]))->configureServiceManager($pluginManager);

    return $pluginManager;
  }
}
/*In the ConfigProvider of the module or global config*/
class ConfigProvider
{
/**
 * Returns the configuration array
 *
 * To add a bit of a structure, each section is defined in a separate
 * method which returns an array with its configuration.
 *
 */
   public function __invoke() : array
   {
    return [
        'dependencies' => $this->getDependencies(),
        'routes' => $this->getRoutes(),
        'i-implementations-config-key' => $this->getIConcreteImplementations(),
    ];
   }
   public function getIConcreteImplementations() : array
   {
    return [
        'factories' => [
            A::class => AFactory::class,
            B::class => InvokableFactory::class,
        ],
    ];
   }
}
/*I can now be sure that I am injecting an array of I implementations into my Service*/
class ServiceFactory
{
    public function __invoke(ContainerInterface $container) : Service
    {
        $pluginManager = $container->get(IPluginManager::class);

        $impl = $pluginManager->getIConcreteImplementations();

        return new Service($impl);
    }
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49798179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档