Skip to main content

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
MethodBehavior
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.

note

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.