Dependency Injection Container
Both the plugin and theme include a custom DI container with auto-wiring capabilities.
Plugin Container
Located at wp-ecommerce-core/includes/Container.php.
Registering Services
// Singleton — same instance every time
$container->singleton(ProductService::class, function ($c) {
return new ProductService(
$c->make(ProductRepository::class)
);
});
// Factory — new instance every time
$container->bind(Cart::class, function ($c) {
return new Cart($c->make(CartStorage::class));
});
Resolving Services
// Explicit resolution
$productService = $container->make(ProductService::class);
// Auto-wiring — resolves constructor dependencies automatically
$service = $container->make(OrderService::class);
// If OrderService requires ProductService in its constructor,
// the container will resolve it automatically
Accessing the Container
// From anywhere in the plugin
$container = \WPECommerce\Core\Bootstrap::getInstance()->getContainer();
$service = $container->make(ProductService::class);
Theme Container
Located at flavor-starter/inc/core/Container.php. Same API as the plugin container.
Accessing via Helper
// flavor_app() returns the Bootstrap singleton
$bootstrap = flavor_app();
// Access theme services
$moduleManager = flavor_app()->getModuleManager();
Best Practices
- Register in Bootstrap — All services should be registered during the bootstrap phase
- Prefer constructor injection — Let the container resolve dependencies
- Use interfaces — Register interfaces, not concrete classes
- Singletons for services — Use
singleton()for stateless services - Factories for stateful objects — Use
bind()for objects that hold state
// Good — interface binding
$container->singleton(
ProductRepositoryInterface::class,
ProductRepository::class
);
// Good — constructor injection
class OrderService
{
public function __construct(
private ProductRepositoryInterface $products,
private PaymentGateway $payments
) {}
}