This content may be out-of-date

This book was written circa 2022, when Joomla 4 was still a new thing. It has not been updated for Joomla 5 and beyond, and it's no longer being worked on. You can usually find more up-to-date information in the official Joomla! Manual.

Service Provider

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;