Jump to main content Jump to doc navigation

Dependency Injection Container

Joshua Lückers Mark Hamstra Sergey Shlokov

Last updated Dec 10th, 2021 | Page history | Improve this page | Report an issue

MODX 3 introduces a Dependency Injection Container, based on Pimple 3, that holds core services and custom services.

The container is available in modX:$services, meaning it is typically accessible in one of the following ways:

  • $modx->services (in snippets, plugins, etc)
  • $this->modx->services (in controllers, processors, etc)
  • $this->xpdo->services (in model classes)

Available Services

At this time, the following services are automatically registered in the core:

  • config: returns an array of configuration properties.

Loading Services

To load a service from the container, call the get method (and/or has() method to first check if it exists) with the ID for the service.

try {
    $config = $modx->services->get('config');
}
catch (ContainerExceptionInterface $e) {
    // handle the thing not being available
}

Or:

$service = null;
try {
    if ($modx->services->has('custom_service')) {
        $service = $modx->services->get('custom_service');
    }
}
catch (ContainerExceptionInterface $e) {
    // handle the thing not being available
}

A service existing (i.e. has() returning true) is not a guarantee that it wont cause an exception when get() is called for it.

Injecting Services

The recommended way to inject or overwrite services in an extension is through a namespace's bootstrap.php file, which runs as early in the initialisation process as possible.

For example, you may call:

$modx->services->add('my_service', function($c) use ($modx) {
    return new MyPackage\MyService($modx);
});

You can use proper dependency injection by passing in the required services. Hypothetical example:

$modx->services->add('my_service', function($c) use ($modx) {
    return new MyPackage\MyService($c['sessions'], $c['parser']);
});

If you require a new instance to be returned for each service request, use the factory() method:

$modx->services['my_service'] = $modx->services->factory(function($c) use ($modx) {
    return new MyPackage\MyService($modx);
});

To extend a previously defined service, use extend:

$modx->services->extend('existing_service', function($existing, $c) use ($modx) {
    $existing->...();
    return $existing;
});

See the Pimple documentation for more information.

Support the team building MODX with a monthly donation.

The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.

Backers

  • modmore
  • STERC
  • Digital Penguin
  • Jens Wittmann – Gestaltung & Entwicklung
  • Fabian Christen
  • Dannevang Digital
  • Sepia River Studios
  • Chris Fickling
  • CrewMark
  • deJaya
  • eydolan
  • Following Sea
  • Lefthandmedia
  • Murray Wood
  • Anton Tarasov
  • Stéphane Jäggi
  • Raffy
  • Snow Creative
  • Nick Clark
  • A. Moreno
  • JT Skaggs
  • Helen
  • YJ
  • krisznet
  • Richard
  • Yanni

Budget

$311 per month—let's make that $500!

Learn more