Zend Framework - Trình quản lý dịch vụ

Zend Framework bao gồm một triển khai mẫu định vị dịch vụ mạnh mẽ được gọi là zend-servicemanager. Zend framework sử dụng rộng rãi trình quản lý dịch vụ cho tất cả các chức năng của nó. Trình quản lý dịch vụ cung cấp một bản tóm tắt cấp cao cho Zend Framework. Nó cũng tích hợp độc đáo với tất cả các thành phần khác của Zend Framework.

Cài đặt Trình quản lý Dịch vụ

Thành phần Trình quản lý dịch vụ có thể được cài đặt bằng cách sử dụng composer dụng cụ.

composer require zendframework/zend-servicemanager

Thí dụ

Đầu tiên, tất cả các dịch vụ cần được đăng ký vào trình quản lý dịch vụ. Sau khi các dịch vụ được đăng ký vào hệ thống quản lý máy chủ, nó có thể được truy cập bất cứ lúc nào với nỗ lực tối thiểu. Người quản lý dịch vụ cung cấp rất nhiều tùy chọn để đăng ký dịch vụ. Một ví dụ đơn giản như sau:

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

Đoạn mã trên đăng ký stdClass vào hệ thống bằng cách sử dụng FactoryLựa chọn. Bây giờ, chúng ta có thể lấy một phiên bản của stdClass bất kỳ lúc nào bằng cách sử dụngget() phương pháp của người quản lý dịch vụ như hình dưới đây.

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

Phương thức get () chia sẻ đối tượng được truy xuất và do đó, đối tượng được trả về bằng cách gọi phương thức get () nhiều lần là một và cùng một thể hiện. Để có được một phiên bản khác nhau mọi lúc, trình quản lý dịch vụ cung cấp một phương pháp khác, đó làbuild() phương pháp.

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

Đăng ký người quản lý dịch vụ

Trình quản lý dịch vụ cung cấp một tập hợp các phương pháp để đăng ký một thành phần. Một số phương pháp quan trọng nhất được đưa ra dưới đây:

  • Phương pháp nhà máy
  • Phương pháp nhà máy trừu tượng
  • Phương pháp khởi tạo
  • Phương thức nhà máy ủy quyền

Chúng ta sẽ thảo luận chi tiết từng điều này trong các chương sắp tới.

Phương pháp nhà máy

Một nhà máy về cơ bản là bất kỳ lớp nào có thể gọi hoặc bất kỳ lớp nào triển khai FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).

FactoryInterface có một phương thức duy nhất -

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

Chi tiết đối số của FactoryInterface như sau:

  • container (ContainerInterface)- Đây là giao diện cơ sở của ServiceManager. Nó cung cấp một tùy chọn để nhận các dịch vụ khác.

  • requestedName - Đó là tên dịch vụ.

  • options - Nó cung cấp các tùy chọn bổ sung cần thiết cho dịch vụ.

Hãy để chúng tôi tạo một lớp đơn giản thực hiện FactoryInterface và xem cách đăng ký lớp đó.

Kiểm tra lớp - Đối tượng được lấy

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

Các Test lớp phụ thuộc vào stdClass.

Lớp TestFactory - Lớp để khởi tạo đối tượng thử nghiệm

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

TestFactory sử dụng một vùng chứa để lấy stdClass, tạo thể hiện của lớp Test và trả về nó.

Đăng ký và sử dụng Zend Framework

Bây giờ chúng ta hãy hiểu cách đăng ký và sử dụng Zend Framework.

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

Người quản lý dịch vụ cung cấp một nhà máy đặc biệt được gọi là InvokableFactoryđể truy xuất bất kỳ lớp nào không có phụ thuộc. Ví dụ,stdClass có thể được cấu hình bằng InvokableFactory vì stdClass không phụ thuộc vào bất kỳ lớp nào khác.

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

Một cách khác để truy xuất một đối tượng mà không cần triển khai FactoryInterface hoặc sử dụng InvokableFactory đang sử dụng phương pháp nội tuyến như được đưa ra bên dưới.

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

Phương pháp nhà máy trừu tượng

Đôi khi, chúng ta có thể cần tạo các đối tượng mà chúng ta chỉ biết đến trong thời gian chạy. Tình huống này có thể được xử lý bằng cách sử dụngAbstractFactoryInterface, có nguồn gốc từ FactoryInterface.

AbstractFactoryInterface định nghĩa một phương thức để kiểm tra xem đối tượng có thể được tạo ở phiên bản được yêu cầu hay không. Nếu có thể tạo đối tượng, nó sẽ tạo đối tượng bằng cách sử dụng__invokemethod của FactoryInterface và trả lại nó.

Chữ ký của AbstractFactoryInterface như sau:

public function canCreate(ContainerInterface $container, $requestedName)

Phương pháp khởi tạo

Phương thức khởi tạo là một tùy chọn đặc biệt để thêm phụ thuộc cho các dịch vụ đã được tạo. Nó thực hiệnInitializerInterface và chữ ký của phương pháp duy nhất có sẵn như sau:

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

Trong ví dụ trên, phương thức kiểm tra xem phiên bản có thuộc kiểu EventManagerAwareInterface hay không. Nếu nó thuộc loạiEventManagerAwareInterface, nó đặt đối tượng trình quản lý sự kiện, nếu không thì không. Vì phương thức có thể có hoặc không thiết lập sự phụ thuộc, nó không đáng tin cậy và tạo ra nhiều vấn đề về thời gian chạy.

Phương pháp nhà máy ủy quyền

Zend Framework hỗ trợ mẫu người ủy quyền thông qua DelegatorFactoryInterface. Nó có thể được sử dụng để trang trí dịch vụ.

Chữ ký của hàm này như sau:

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

Đây, $callback chịu trách nhiệm trang trí phiên bản dịch vụ.

Dịch vụ lười biếng

Dịch vụ lười biếng là một trong những dịch vụ sẽ không được khởi tạo hoàn toàn tại thời điểm tạo. Chúng chỉ được tham chiếu và chỉ khởi tạo khi thực sự cần thiết. Một trong những ví dụ điển hình là kết nối cơ sở dữ liệu, có thể không cần thiết ở mọi nơi. Nó là một nguồn tài nguyên đắt tiền cũng như tốn nhiều thời gian để tạo ra. Zend framework cung cấpLazyServiceFactory được chuyển hóa từ DelegatorFactoryInterface, có thể tạo ra dịch vụ lười biếng với sự trợ giúp của Delegator khái niệm và trình quản lý proxy bên thứ 3, được gọi là ocramius proxy manager.

Plugin Manager

Trình quản lý plugin mở rộng trình quản lý dịch vụ và cung cấp chức năng bổ sung như xác thực phiên bản. Zend Framework sử dụng rộng rãi trình quản lý plugin.

Ví dụ: tất cả các dịch vụ xác thực đều có ValidationPluginManager.

Tùy chọn cấu hình

Trình quản lý dịch vụ cung cấp một số tùy chọn để mở rộng tính năng của trình quản lý dịch vụ. họ đangshared, shared_by_defaultaliases. Như chúng ta đã thảo luận trước đó, các đối tượng đã truy xuất được chia sẻ giữa các đối tượng được yêu cầu theo mặc định và chúng ta có thể sử dụngbuild()phương pháp để có được một đối tượng riêng biệt. Chúng tôi cũng có thể sử dụngsharedtùy chọn để chỉ định dịch vụ nào sẽ được chia sẻ. Cácshared_by_default giống như shared , ngoại trừ việc nó áp dụng cho tất cả các dịch vụ.

$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 
]);

Các aliasestùy chọn có thể được sử dụng để cung cấp một tên thay thế cho các dịch vụ đã đăng ký. Điều này có cả lợi thế và bất lợi. Về mặt tích cực, chúng tôi có thể cung cấp các tên viết tắt thay thế cho một dịch vụ. Tuy nhiên, đồng thời, tên có thể trở nên sai ngữ cảnh và gây ra lỗi.

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