diff --git a/docs/building-extensions/plugins/advanced-plugin-features.md b/docs/building-extensions/plugins/advanced-plugin-features.md new file mode 100644 index 00000000..9490041d --- /dev/null +++ b/docs/building-extensions/plugins/advanced-plugin-features.md @@ -0,0 +1,70 @@ +Advanced Plugin features +======================== + +## Lazy Subscriber + +The decorator `Joomla\CMS\Event\LazyServiceSubscriber` allows to instantiate the plugin with heavy dependencies only when the event is actually dispatched. +The plugin should implement `Joomla\Event\SubscriberInterface` to be able to use decorator. + +Note that the use of the lazy decorator does not make sense when the plugin is subscribed to events that happen regularly, like `onAfterInitialise`. + +Additionally, the interface `Joomla\CMS\Event\LazySubscriberInterface` allows to use [`LazyServiceEventListener`](https://github.com/joomla-framework/event/blob/2.0-dev/src/LazyServiceEventListener.php), however the plugin should implement it on its own. + +### Example usage of the lazy subscriber decorator for the plugin with heavy dependencies: + +Code for `plugins/system/example/services/provider.php`. + +**Before, regular plugin service:** +```php +return new class () implements ServiceProviderInterface { + public function register(Container $container) + { + $container->set( + PluginInterface::class, + function (Container $container) { + $heavyDependency1 = $container->get(Foo::class); + $heavyDependency2 = $container->get(Bar::class); + + return new ExamplePlugin( + $container->get(DispatcherInterface::class), + (array) PluginHelper::getPlugin('system', 'example'), + $heavyDependency1, + $heavyDependency2 + ); + } + ); + } +} +``` +**After, plugin service with LazyServiceSubscriber:** + +```php +return new class () implements ServiceProviderInterface { + public function register(Container $container) + { + $container->set( + ExamplePlugin::class, + function (Container $container) { + $heavyDependency1 = $container->get(Foo::class); + $heavyDependency2 = $container->get(Bar::class); + + return new ExamplePlugin( + $container->get(DispatcherInterface::class), + (array) PluginHelper::getPlugin('system', 'example'), + $heavyDependency1, + $heavyDependency2 + ); + } + )->set( + PluginInterface::class, + function (Container $container) { + return new LazyServiceSubscriber($container, ExamplePlugin::class); + } + ); + } +} +``` + +With the regular plugin service the dependencies are instantiated whenever the plugin is instantiated, ie when its plugin type is imported. + +With the Lazy Subscriber the plugin service and its dependencies are instantiated only whenever one of the events to which the plugin service subscribes is triggered. diff --git a/migrations/51-52/new-features.md b/migrations/51-52/new-features.md index 246c7074..eac04723 100644 --- a/migrations/51-52/new-features.md +++ b/migrations/51-52/new-features.md @@ -16,3 +16,12 @@ This new feature adds a "total" counter at the bottom near the pagination in Joo displaying the number of items available after applying filters for easier item management. PR: [43575](https://github.com/joomla/joomla-cms/pull/43575) + + +#### New lazy decorator for Plugins + +Adding Lazy Subscriber interface and decorator. +The decorator allows to instantiate the plugin with heavy dependencies only when the event is actually dispatched. +PR: https://github.com/joomla/joomla-cms/pull/43658 + +More details here: [Lazy Subscriber](https://manual.joomla.org/docs/building-extensions/plugins/advanced-plugin-features#lazy-subscriber).