Service Providers & Dependency Injection
Service Providers
Service providers are the central place to register application services, bindings, and event listeners. They are stored in app/Providers.
- Use service providers to bind interfaces to implementations, register singletons, and configure third-party packages.
- Split custom logic into multiple providers for clarity (e.g.,
AppServiceProvider,AuthServiceProvider,EventServiceProvider). - Register providers in
config/app.phpunder theprovidersarray.
Example: Registering a binding
public function register()
{
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
}
Dependency Injection
Dependency injection allows you to automatically resolve class dependencies. Use constructor injection for controllers, services, and jobs.
- Prefer interfaces for type-hinting to allow flexibility and easier testing.
- Use Laravel's automatic resolution for dependencies in controllers and jobs.
Example: Controller injection
class UserController extends Controller
{
protected $users;
public function __construct(UserRepositoryInterface $users)
{
$this->users = $users;
}
}
Singleton vs Transient
- Register singletons for shared services that should only have one instance per request lifecycle:
$this->app->singleton(CacheService::class, function ($app) { return new CacheService(); }); - Register transient bindings for services that should be resolved fresh each time:
$this->app->bind(NotificationService::class, function ($app) { return new NotificationService(); });
Best Practices
- Use dependency injection for all services and repositories.
- Avoid using the
app()helper or service container directly in controllers. - Document service provider logic with comments.
- Use interfaces for all injected dependencies to improve testability.
- Keep service providers focused and avoid mixing unrelated logic.
Example: Custom Service Provider
class CustomServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(CustomService::class, function ($app) {
return new CustomService();
});
}
public function boot()
{
// Boot logic, e.g., event listeners
}
}