什么是服务容器
Laravel 的服务容器是用来管理类依赖并进行依赖注入的机制。所谓依赖注入,指的是通过构造器或(在某些情况下)setter 方法,将类所需的依赖「注入」到类中。 来看下面的示例:PodcastController 需要从 Apple Music 等数据源获取 Podcast。因此我们将能够获取 Podcast 的服务注入给它。这样一来,在测试时就可以很方便地替换 AppleMusic 服务的 mock(假实现)。
深入理解服务容器对于构建大型 Laravel 应用不可或缺,也有助于为 Laravel 核心贡献代码。
零配置解析
如果类只依赖其他具体类(而不是接口),就无需告诉容器如何解析它。例如你在routes/web.php 中写下这段代码:
这个例子把类定义在路由文件内只是为了演示。真实应用中,服务类请放到
app/Services 目录下。Service 类并注入到路由处理器中。你无需任何配置就能享受依赖注入。
Laravel 应用中编写的许多类(控制器、事件监听器、中间件等)都会通过容器自动注入依赖。
绑定
基本绑定
大部分绑定都会在服务提供者中注册。在服务提供者中可以通过$this->app 属性访问容器。
bind
bind 方法把类或接口名与一个闭包组合,注册为绑定。
App 门面。
不依赖接口的类无需向容器注册绑定。容器可以通过反射自动解析这类对象。
singleton
singleton 方法会让某个类或接口只解析一次。解析出来的单例,后续对容器的调用都会返回同一实例。
instance
也可以通过instance 方法把已有的对象实例绑定到容器上。之后对该绑定的解析都会返回该实例。
将接口绑定到实现
服务容器的一个强大功能是可以把接口绑定到特定实现。以EventPusher 接口与 RedisEventPusher 实现为例:
EventPusher 实现的类注入 RedisEventPusher。你只需在构造器中类型提示 EventPusher 接口即可。
自动解析(通过类型提示进行 DI)
服务容器在解析控制器、事件监听器、中间件等类时,会读取构造器的类型提示并自动注入依赖。UserRepository 不依赖接口,就无需向容器注册。当访问对应路由时,容器会自动解析依赖并注入控制器。
从容器解析
make 方法
使用make 方法可以从容器中解析类实例。
makeWith 方法额外传入参数。
自动注入
实际开发中很少直接调用make。只要在容器负责解析的类(控制器、事件监听器、中间件等)的构造器上加上类型提示,容器就会自动注入依赖。
门面与容器的关系
Laravel 的门面为容器中的对象提供了静态接口。例如,Cache::get() 在内部会从容器获取 Cache 服务并调用。
构造器注入实战示例
来看实际应用中一种典型模式。1
定义接口
2
创建实现类
3
在服务提供者中绑定
4
在控制器中接收注入
Stripe 换成其他供应商,也只需修改一处绑定。
下一步
服务提供者
学习如何通过服务提供者注册绑定。