Customization
The framework package is intentionally small, so customization mostly happens by composing extra
providers around FrameworkServiceProvider
.
Add your own provider
Register your application provider after the framework provider:
use App\ServiceProvider\AppServiceProvider;
use FastForward\Framework\ServiceProvider\FrameworkServiceProvider;
use function FastForward\Container\container;
$container = container(
FrameworkServiceProvider::class,
AppServiceProvider::class,
);
This keeps the framework defaults while giving your application room to add domain-specific services.
Override an existing service identifier
AggregateServiceProvider
merges factory arrays in provider order. In practice, that means a
later provider can replace an earlier factory when both use the same service identifier.
This is the simplest override strategy when you want to swap a default implementation entirely.
Decorate an existing service with extensions
If you want to wrap an existing service instead of replacing it, use provider extensions:
use Interop\Container\ServiceProviderInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Client\ClientInterface;
final class DecoratorServiceProvider implements ServiceProviderInterface
{
public function getFactories(): array
{
return [];
}
public function getExtensions(): array
{
return [
ClientInterface::class => static function (
ContainerInterface $container,
ClientInterface $client,
): ClientInterface {
return new LoggingClient($client);
},
];
}
}
The aggregate provider composes extensions in order, so later decorators wrap earlier ones.
Replace LoggingClient
with your own decorator implementation.
Documented limitations
- This package does not define framework-specific aliases or facades of its own.
- The convenience aliases and helper factories live in the downstream HTTP factory package.
- Listener registration for the event-dispatcher stack is driven by the
Psr\EventDispatcher\ListenerProviderInterfaceconfiguration entry. - If you need additional providers for config-driven applications, register them explicitly or
list them in
FastForward\Container\ContainerInterface::classinside your config object.
Customize event listener registration
You can extend the framework's event behavior without replacing the framework provider itself:
use FastForward\Config\ArrayConfig;
use FastForward\Container\ContainerInterface;
use FastForward\Framework\ServiceProvider\FrameworkServiceProvider;
use Psr\EventDispatcher\ListenerProviderInterface;
use function FastForward\Container\container;
$config = new ArrayConfig([
ContainerInterface::class => [
FrameworkServiceProvider::class,
],
ListenerProviderInterface::class => [
SendWelcomeEmailListener::class,
AuditTrailListenerProvider::class,
],
]);
$container = container($config);
This lets you mix invokable listeners, subscriber classes, attributed listeners, and custom listener-provider implementations without replacing the framework's default dispatcher wiring.
Good customization defaults for new projects
- Start with
FrameworkServiceProvideronly. - Add one application provider for your own services.
- Reach for overrides only after you know which service identifier you need to replace.
- Use extensions when you want to decorate behavior instead of rewriting the original factory.