As discussed in a previous section, the service provider file is mandatory for Joomla 4 native plugins, lives
in the plugin's services
folder and always named provider.php
.
The absolutely minimal minimal service provider file looks like the following:
<?php defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Acme\Plugin\System\Example\Extension\Example; return new class implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('system', 'example'); $subject = $container->get(DispatcherInterface::class); return new Example($subject, $config); } ); } };
As you can see the service provider returns an anonymous PHP class which implements
the Joomla\DI\ServiceProviderInterface
. That's the standard way to extend Joomla's DIC. Joomla creates
a copy of its DIC and uses it as our plugin's own DIC. The service providers we set up in our
plugin stay with our plugin, they do not leak out to the global application scope (the global Joomla DIC you get
through the Joomla\CMS\Factory::getContainer()
static method).
The code in the anonymous function does the bare minimum of setting up a plugin. If you need to register custom service providers for your plugin do it before this code.
The return line creates the plugin object from the plugin's class. If you need to push services into your plugin's object instance you will have to replace that line with something like this:
$plugin = Example($subject, $config); $plugin->setMyCustomService($container->get(MyCustomService::class)); return $plugin;