Aikeedo resolves your entry class, request handlers, listeners and command handlers from its dependency injection container. Anything you type-hint in a constructor is built and injected for you, and that is how a plugin reaches the application.
Constructor injection
The container autowires concrete classes and any interface the core has bound to an implementation. Your own classes are autowired too, so a service of yours can depend on another service of yours without registration.
Injecting configuration and settings
Scalar values come from the container by ID, using the #[Inject] attribute:
Always give injected options a default and a nullable type. An option that was never saved resolves to null, and settings pages are often empty on a fresh installation.
Inside boot() you can also read a value imperatively:
Services a plugin commonly injects
Calling an external API
Use the PSR-18 client the application already configures, instead of bundling your own HTTP library:
safe_json_encode() is a global helper the application autoloads. It encodes without throwing on invalid UTF-8.
The command bus
Aikeedo separates intent from execution. A command is a data object tagged with the handler that executes it, and Dispatcher::dispatch() resolves the handler from the container and runs it synchronously.
Dispatching core commands
Defining your own
src/Application/Commands/SendGreetingCommand.php
src/Application/CommandHandlers/SendGreetingCommandHandler.php
Dispatching an unhandled command throws Shared\Infrastructure\CommandBus\Exception\NoHandlerFoundException. There is no queue: handlers run in the current request.
Registering your own services
You rarely need to register anything, because the container autowires concrete classes. Register explicitly when you want to bind an interface to an implementation that other plugins can swap, or when you’re publishing an extension point. See Custom extension points.