Skip to main content

Service Providers

Service providers are the primary extension point for wiring third-party libraries and custom services into the container. They follow a two-phase boot: first all register() calls run, then all boot() calls run. This guarantees that every service is registered before any service tries to use another.

Creating a provider

// app/Providers/MailServiceProvider.php
namespace App\Providers;

use App\Services\Mailer;
use MaplePHP\Core\Support\ServiceProvider;
use Psr\Container\ContainerInterface;

class MailServiceProvider extends ServiceProvider
{
public function register(ContainerInterface $container): void
{
$container->set('mailer', new Mailer(
host: env('MAIL_HOST'),
port: (int) env('MAIL_PORT', 587),
));
}

public function boot(): void
{
// Runs after all providers have registered.
// Safe to resolve other services here.
}
}

Registering a provider

Add the fully-qualified class name to configs/services.php:

// configs/services.php
return [
"providers" => [
\MaplePHP\Core\Providers\DatabaseProvider::class,
\App\Providers\MailServiceProvider::class,
],
];

Providers are registered in order, then booted in order.

Built-in providers

ProviderWhat it registers
MaplePHP\Core\Providers\DatabaseProviderDoctrine DBAL connection, DB singleton, QueryBuilder
MaplePHP\Core\Providers\TwigServiceProviderTwig\Environment with auto-caching based on environment

DatabaseProvider must be present for DB::table() to work. Remove it if you are not using the database layer.

TwigServiceProvider must be present to use the Twig helper in controllers. See Twig Templates →.

Two-phase boot

The two-phase design prevents ordering issues when one service depends on another:

  1. register() — bind services into the container. No other service should be resolved here.
  2. boot() — all services are now registered. Safe to resolve and configure them.

This means you can define providers in any order in configs/services.php without worrying about dependencies between them.

For simpler interface-to-class wiring that does not require a full provider, use Bindings →.