📜  Zend框架-服务管理器

📅  最后修改于: 2020-10-16 07:36:31             🧑  作者: Mango


Zend框架包含一个功能强大的服务定位器模式实现,称为zend-servicemanager 。 Zend框架广泛使用服务管理器来实现其所有功能。服务管理器为Zend框架提供了高级抽象。它还与Zend框架的所有其他组件很好地集成在一起。

安装服务管理器

可以使用作曲工具安装Service Manager组件。

composer require zendframework/zend-servicemanager

首先,所有服务都需要注册到服务管理器中。一旦将服务注册到服务器管理器系统中,就可以在任何时间以最小的努力对其进行访问。服务管理器提供许多选项来注册服务。一个简单的例子如下-

use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\Factory\InvokableFactory; 
use stdClass;  
$serviceManager = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class,], 
]);

上面的代码使用Factory选项将stdClass注册到系统中。现在,我们可以使用服务管理器的get()方法随时获取stdClass的实例,如下所示。

use Zend\ServiceManager\ServiceManager;  
$object = $serviceManager->get(stdClass::class);

get()方法共享检索到的对象,因此,多次调用get()方法返回的对象是一个实例。为了每次都获得不同的实例,服务管理器提供了另一种方法,即build()方法。

use Zend\ServiceManager\ServiceManager;  
$a = $serviceManager->build(stdClass::class); 
$b = $serviceManager->build(stdClass::class);

服务经理注册

服务管理器提供了一组方法来注册组件。一些最重要的方法如下-

  • 工厂方法
  • 抽象工厂方法
  • 初始化方法
  • 委托人工厂方法

我们将在接下来的章节中详细讨论每一个。

工厂方法

工厂基本上是任何可调用的或实现FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface)的任何类。

FactoryInterface有一个方法-

public function __invoke(ContainerInterface $container, $requestedName, array 
   $options = null)

FactoryInterface的参数详细信息如下-

  • container(ContainerInterface) -它是ServiceManager的基本接口。它提供了获取其他服务的选项。

  • requestedName-这是服务名称。

  • options-它提供了服务所需的其他选项。

让我们创建一个实现FactoryInterface的简单类,并查看如何注册该类。

类测试-要检索的对象

use stdClass;  
class Test { 
   public function __construct(stdClass $sc) { 
      // use $sc 
   } 
} 

Test类取决于stdClass。

TestFactory类-初始化测试对象的类

class TestFactory implements FactoryInterface { 
   public function __invoke(ContainerInterface $container, $requestedName, 
      array $options = null) { 
      $dep = $container->get(stdClass::class); 
      return new Test($dep); 
   } 
}

TestFactory使用容器来检索stdClass,创建Test类的实例,然后将其返回。

Zend框架的注册和使用

现在让我们了解如何注册和使用Zend框架。

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class, 
      Test::class => TestFactory::class] 
]); 
$test = $sc->get(Test::class);

服务管理器提供了一个名为InvokableFactory的特殊工厂,以检索任何没有依赖关系的类。例如,stdClass的可使用由于stdClass的不依赖于任何其他类InvokableFactory进行配置。

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class] 
]);  
$stdC = $sc->get(stdClass::class); 

但没有实施FactoryInterface或使用InvokableFactory使用内联方法如下面给出的另一种方式来检索对象。

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class, 
      Test::class => function(ContainerInterface $container, $requestedName) { 
         $dep = $container->get(stdClass::class); 
         return new Test($dep); 
      }, 
   ], 
]);

抽象工厂方法

有时,我们可能需要创建对象,而这些对象只有在运行时才知道。可以使用从FactoryInterface派生的AbstractFactoryInterface来处理这种情况。

AbstractFactoryInterface定义了一种方法,用于检查是否可以在请求的实例处创建对象。如果可以创建对象,它将使用FactoryInterface的__invoke方法创建对象并返回它。

AbstractFactoryInterface的签名如下-

public function canCreate(ContainerInterface $container, $requestedName) 

初始化方法

Initializer方法是一个特殊选项,可以为已经创建的服务注入附加的依赖关系。它实现了InitializerInterface ,唯一方法的签名如下:

public function(ContainerInterface $container, $instance)  
function(ContainerInterface $container, $instance) { 
   if (! $instance instanceof EventManagerAwareInterface) { 
      return; 
   } 
   $instance->setEventManager($container->get(EventManager::class)); 
} 

在上面的示例中,该方法检查实例是否为EventManagerAwareInterface类型。如果其类型为EventManagerAwareInterface ,则设置事件管理器对象,否则不设置。由于该方法可能会或可能不会设置依赖项,因此它不可靠,并会导致许多运行时问题。

委托工厂方法

Zend Framework通过DelegatorFactoryInterface支持委托人模式。它可以用来装饰服务。

该函数的签名如下-

public function __invoke(ContainerInterface $container, 
   $name, callable $callback, array $options = null 
); 

在这里, $ callback负责装饰服务实例。

懒惰服务

惰性服务是在创建时不会完全初始化的那些服务之一。它们只是被引用,仅在真正需要时才进行初始化。最好的例子之一是数据库连接,它不一定在所有地方都需要。它是一种昂贵的资源,并且创建过程很耗时。 Zend Framework提供LazyServiceFactoryDelegatorFactoryInterface,能产生懒惰的服务与委托人概念的帮助和第三方代理经理,这就是所谓的ocramius代理经理的。

插件管理器

插件管理器扩展了服务管理器并提供了其他功能,例如实例验证。 Zend Framework广泛使用插件管理器。

例如,所有验证服务都在ValidationPluginManager下

配置选项

服务管理器提供了一些选项来扩展服务管理器的功能。它们是共享的,shared_by_default别名。如前所述,默认情况下,检索到的对象在请求的对象之间共享,并且我们可以使用build()方法来获得一个不同的对象。我们还可以使用shared选项来指定要共享的服务。 shared_by_default共享功能相同,不同之处在于它适用于所有服务。

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class 
   ], 
   'shared' => [ 
      stdClass::class => false // will not be shared 
   ], 
   'shared_by_default' => false, // will not be shared and applies to all service 
]);

别名选项可用于为注册服务提供备用名称。这既有优点也有缺点。从积极的方面来说,我们可以为服务提供替代的简称。但是,与此同时,该名称可能会脱离上下文并引入错误。

aliases' => ['std' => stdClass::class, 'standard' => 'std']