geekcell/container-facade
Laravel package that adds lightweight container-backed facades, letting you resolve services from the IoC container via a simple static-like interface. Useful for organizing service access and reducing boilerplate when binding and retrieving dependencies.
Installation
composer require geekcell/container-facade
Register the Service Provider
Add to config/app.php under providers:
Geekcell\ContainerFacade\ContainerFacadeServiceProvider::class,
Publish Config (Optional)
php artisan vendor:publish --provider="Geekcell\ContainerFacade\ContainerFacadeServiceProvider"
Define a Static Facade
Create a facade class extending Geekcell\ContainerFacade\ContainerFacade:
namespace App\Facades;
use Geekcell\ContainerFacade\ContainerFacade;
class MyServiceFacade extends ContainerFacade
{
protected static $serviceName = 'my.service'; // Matches your container binding
}
Bind the Service in Container In a service provider:
$this->app->bind('my.service', function ($app) {
return new \App\Services\MyService();
});
Use the Facade
use App\Facades\MyServiceFacade;
MyServiceFacade::doSomething(); // Resolves via container
Replace direct instantiation of a service with a facade for cleaner, testable code:
// Before
$service = new MyService();
// After
MyServiceFacade::doSomething();
Identify Reusable Services Target services used across multiple classes (e.g., logging, caching, APIs).
Facade Naming Convention
Use *Facade suffix (e.g., LoggerFacade, CacheFacade) for clarity.
Service Binding Bind interfaces or concrete classes to the container for flexibility:
$this->app->bind('App\Contracts\LoggerInterface', function ($app) {
return new \App\Services\LogService();
});
Facade Methods Mirror the service’s public methods in the facade:
class LoggerFacade extends ContainerFacade
{
protected static $serviceName = 'App\Contracts\LoggerInterface';
public static function emergency($message) {
return static::getContainer()->get(static::$serviceName)->emergency($message);
}
}
$this->app->instance('my.service', Mockery::mock(\App\Services\MyService::class));
getServiceName():
protected static function getServiceName()
{
return config('services.dynamic_key');
}
Circular Dependencies Facades resolve services on-demand, which can hide circular dependency issues. Test thoroughly.
Container Not Bootstrapped Facades fail silently if the container isn’t initialized (e.g., in non-Laravel contexts). Ensure the service provider is registered.
Static Facade State Facades cache the resolved service instance. Clear the cache if the service is stateful:
MyServiceFacade::flush(); // If implemented
Namespace Collisions Ensure facade namespaces are unique to avoid autoloading conflicts.
$serviceName matches the container key.app()->bound('service.name') to verify bindings.config/container-facade.php) for global settings (e.g., default namespace for facades).setServiceName() dynamically if needed:
MyServiceFacade::setServiceName('new.service');
Custom Resolution Logic
Override resolveService() to add pre/post-resolution logic:
protected static function resolveService()
{
$service = static::getContainer()->get(static::$serviceName);
// Add logic (e.g., logging, middleware)
return $service;
}
Facade Events Trigger events before/after resolution by extending the facade:
protected static function beforeResolve()
{
event(new ServiceResolving(static::$serviceName));
}
Facade Groups Create a base facade for shared functionality:
abstract class BaseFacade extends ContainerFacade
{
protected static function getContainer() { /* custom logic */ }
}
How can I help you explore Laravel packages today?