What is the service container
Laravel’s service container is a mechanism for managing class dependencies and performing dependency injection. Dependency injection means the dependencies a class needs are “injected” into the class via the constructor, or in some cases, setter methods. Look at the following example.PodcastController needs to fetch podcasts from a data source like Apple Music. So we inject a service that can fetch podcasts. By injecting the service, we can easily swap in a mock (dummy implementation) of the AppleMusic service during testing.
A deep understanding of the service container is essential for building a large Laravel application. It also helps you contribute to the Laravel core itself.
Zero-configuration resolution
If a class has no dependencies or only depends on other concrete classes (not interfaces), the container does not need to be instructed on how to resolve that class. For example, you may place the following code in yourroutes/web.php file:
This example defines a class inside the route file for demonstration purposes. In a real application, service classes should be defined in the
app/Services directory.Service class and injects it into the route’s handler. You get the benefits of dependency injection without needing any configuration files.
Many classes you write in a Laravel application—controllers, event listeners, middleware, and so on—automatically have their dependencies injected via the container.
Binding
Basic binding
Almost all of your bindings will be registered inside service providers. Inside a service provider, you have access to the container via the$this->app property.
bind
Use thebind method to register a binding, passing the class or interface name that we wish to register along with a closure.
App facade.
There is no need to bind classes into the container if they do not depend on any interfaces. The container can resolve these objects automatically using reflection.
singleton
Thesingleton method binds a class or interface such that it is only resolved once. Once a singleton has been resolved, the same instance is returned on subsequent calls into the container.
singletonIf method to register a singleton container binding only if a binding has not already been registered for the given type.
Singleton attribute
Alternatively, you may mark an interface or class with the#[Singleton] attribute to indicate to the container that it should be resolved one time.
Binding scoped singletons
Thescoped method binds a class or interface into the container that should only be resolved one time within a given Laravel request / job lifecycle. While this method is similar to the singleton method, instances registered using the scoped method are flushed whenever the Laravel application starts a new “lifecycle”, such as when a Laravel Octane worker processes a new request or when a queue worker processes a new job.
scopedIf method to register a scoped container binding only if a binding has not already been registered for the given type.
Scoped attribute
Alternatively, you may mark an interface or class with the#[Scoped] attribute to indicate to the container that it should be resolved one time within a given Laravel request / job lifecycle.
instance
You may also bind an existing object instance into the container using theinstance method. The given instance will always be returned on subsequent calls into the container.
Binding interfaces to implementations
One of the powerful features of the service container is its ability to bind an interface to a given implementation. For example, suppose we have anEventPusher interface and a RedisEventPusher implementation.
RedisEventPusher when a class needs an implementation of EventPusher. Then, all you need to do is type-hint the EventPusher interface in a constructor.
Bind attribute
Laravel also provides aBind attribute for added convenience. You can apply this attribute to any interface to tell Laravel which implementation should be automatically injected whenever that interface is requested. When using the Bind attribute, there is no need to perform any additional service registration in your application’s service providers.
In addition, multiple Bind attributes may be placed on an interface in order to configure a different implementation that should be injected for a given set of environments.
Automatic resolution (DI via type hints)
When resolving classes such as controllers, event listeners, and middleware, the service container examines the constructor’s type hints and injects the dependencies automatically.UserRepository doesn’t depend on an interface, you don’t need to register it in the container. Just visit the following route and the container automatically resolves and injects the dependency into the controller.
Resolving from the container
The make method
Use themake method to resolve a class instance from the container.
makeWith method.
Automatic injection
In practice, you’ll rarely need to call themake method directly. Just add type hints to the constructor of a class that the container resolves (controllers, event listeners, middleware, and so on) and the container will inject them automatically.
Facades and the container
Laravel facades provide a static interface to objects in the container. For example,Cache::get() internally retrieves the Cache service from the container and calls the method.
Practical example of constructor injection
Let’s look at a typical pattern in a real application.1
Define the interface
2
Create the implementation class
3
Bind it in a service provider
4
Receive it via injection in a controller
Next steps
Service providers
Learn how to register bindings using service providers.