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 } }
该测试类依赖于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提供LazyServiceFactory从派生DelegatorFactoryInterface,能产生懒惰的服务与的帮助委托者的理念和第三方代理经理,这就是所谓的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']
作者:terry,如若转载,请注明出处:https://www.web176.com/zendframework/308.html