网页 综合 更新时间 2026-11-13 17:31:50

Service Container | Laravel 13.x - The clean stack for Artisans and agents

自动蜘蛛 laravel.com 正文约 6000 字
Service Container | Laravel 13.x - The clean stack for Artisans and agents
The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.
Let's look at a simple example:
In this example, the PodcastController needs to retrieve podcasts from a data source such as Apple Music. So, we will inject a service that is able to retrieve podcasts. Since the service is injected, we are able to easily "mock", or create a dummy implementation of the AppleMusic service when testing our application.
A deep understanding of the Laravel service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself.
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 your routes/web.php file:
In this example, hitting your application's / route will automatically resolve the Service class and inject it into your route's handler. This is game changing. It means you can develop your application and take advantage of dependency injection without worrying about bloated configuration files.
Thankfully, many of the classes you will be writing when building a Laravel application automatically receive their dependencies via the container, including controllers, event listeners, middleware, and more. Additionally, you may type-hint dependencies in the handle method of queued jobs. Once you taste the power of automatic and zero configuration dependency injection it feels impossible to develop without it.
Thanks to zero configuration resolution, you will often type-hint dependencies on routes, controllers, event listeners, and elsewhere without ever manually interacting with the container. For example, you might type-hint the Illuminate\Http\Request object on your route definition so that you can easily access the current request. Even though we never have to interact with the container to write this code, it is managing the injection of these dependencies behind the scenes:
In many cases, thanks to automatic dependency injection and facades, you can build Laravel applications without ever manually binding or resolving anything from the container. So, when would you ever manually interact with the container? Let's examine two situations.
First, if you write a class that implements an interface and you wish to type-hint that interface on a route or class constructor, you must tell the container how to resolve that interface. Secondly, if you are writing a Laravel package that you plan to share with other Laravel developers, you may need to bind your package's services into the container.
Almost all of your service container bindings will be registered within service providers, so most of these examples will demonstrate using the container in that context.
Within a service provider, you always have access to the container via the $this->app property. We can register a binding using the bind method, passing the class or interface name that we wish to register along with a closure that returns an instance of the class:
Note that we receive the container itself as an argument to the resolver. We can then use the container to resolve sub-dependencies of the object we are building.
As mentioned, you will typically be interacting with the container within service providers; however, if you would like to interact with the container outside of a service provider, you may do so via the App facade:
You may use the bindIf method to register a container binding only if a binding has not already been registered for the given type:
For convenience, you may omit providing the class or interface name that you wish to register as a separate argument and instead allow Laravel to infer the type from the return type of the closure you provide to the bind method:
There is no need to bind classes into the container if they do not depend on any interfaces. The container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.
The singleton method binds a class or interface into the container that should only be resolved one time. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container:
You may use the singletonIf method to register a singleton container binding only if a binding has not already been registered for the given type:
Alternatively, you may mark an interface or class with the #[Singleton] attribute to indicate to the container that it should be resolved one time:
The scoped 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 will be flushed whenever the Laravel application starts a new "lifecycle", such as when a Laravel Octane worker processes a new request or when a Laravel queue worker processes a new job:
You may use the scopedIf method to register a scoped container binding only if a binding has not already been registered for the given type:
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:
You may also bind an existing object instance into the container using the instance method. The given instance will always be returned on subsequent calls into the container:
A very powerful feature of the service container is its ability to bind an interface to a given implementation. For example, let's assume we have an EventPusher interface and a RedisEventPusher implementation. Once we have coded our RedisEventPusher im
访问原文 返回搜索 https://laravel.com/framework/docs/container
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。