Container
Introduction
Container is a small IoC container: it resolves classes, injects their constructor dependencies, and holds shared instances. Added in wp-kit 2.4.0.
use YourPlugin\Deps\BitApps\WPKit\Container\Application;
$app = new Application();
$app->bind(Logger::class, FileLogger::class);
$logger = $app->make(Logger::class); // a FileLogger
Bindings
$app->bind(Logger::class, FileLogger::class); // new instance per resolve
$app->singleton(Database::class, function ($container) {
return new Database($container->make(Connection::class));
});
$app->instance(Config::class, $config); // an object you already built
$app->alias('db', Database::class); // resolve by short name
| Method | Behavior |
|---|---|
bind($abstract, $concrete) | Resolves fresh every time |
singleton($abstract, $concrete) | Builds once, returns the same instance after |
instance($abstract, $object) | Registers an existing object |
alias($alias, $abstract) | A second name for the same binding |
make($abstract) | Resolve |
get($id) / has($id) | PSR-style accessors |
bound($abstract) | Is anything registered for this name? |
Autowiring
An unbound class is still resolvable when its constructor type-hints are themselves resolvable:
class ReportService
{
public function __construct(private Database $db, private Logger $logger) {}
}
$app->make(ReportService::class); // Database and Logger injected
A dependency that cannot be resolved — an unbound interface, a scalar with no default — throws BindingResolutionException.
Service providers
Group related bindings in a provider. register() declares bindings; boot() runs after every provider has registered, so it can safely use another provider's services:
use YourPlugin\Deps\BitApps\WPKit\Container\ServiceProvider;
class MailProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Mailer::class);
}
public function boot(): void
{
Hooks::addAction('init', [$this->app->make(Mailer::class), 'listen']);
}
}
$app->register(MailProvider::class);
$app->boot(); // boots every registered provider
$app->booted(); // has boot() already run?
register() is abstract — a provider must implement it. boot() is optional.
This is a standalone container, not a framework-wide one: the router resolves controllers and requests itself and does not consult it. Use it for your own services, and pass what you need into controllers explicitly.