A plugin manager is a service that defines how a plugin is discovered and annotated. Let's look at how the block plugin manager is set up. First, the service for it is defined, like other core services, in the core.services.yml file. You see:
plugin.manager.block:
class: Drupal\Core\Block\BlockManager
parent: default_plugin_manager
This declares the service by a unique name, plugin.manager.block, and defines the class name and the parent service, in this case default_plugin_manager, which was defined earlier as being the DefaultPluginManager class. Most of the work of the plugin manager is done inside the constructor. Looking at the BlockManager::__construct function, we have:
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler)
{
parent::__construct('Plugin/Block', $namespaces, $module_handler,
'Drupal\Core\Block\BlockPluginInterface',
'Drupal\Core\Block\Annotation\Block'); $this->alterInfo('block');
$this->setCacheBackend($cache_backend, 'block_plugins');
}
A lot of the work is handled by the parent, the DefaultPluginManager. It gets the path to use to detect new plugins, in this case plugin/Block--which is how our TestBlock is discovered--then the list of namespaces for Drupal and the module handler for Drupal. The next two define the interface that the plugin is expected to implement and the annotation class that is used to process the plugin's metadata. After this definition, it adds the hook that can be used to alter the plugin: alterInfo('block') becomes hook_block_alter. Finally, the plugins are cached to ensure Drupal doesn't have to go scanning for block plugins on each request.