啥都不说,直接上代码
- class UserController
- {
- private $user;
- function __construct(UserModel $user) {
- $this->user = $user;
- }
- }
- $user = new UserController(new UserMonel());
- ?>
User 控制器依赖 UserModel,实例化的时候,直接注入。
先说 IOC 和 DI 的区别吧!
所以两者有本质上的区别。DI 是 IOC 的一种实现方法(还有 ServiceLocator 等其他设计模式)。 所谓的反转,主要指由 主动依赖 到 被动依赖 。
- //主动依赖
- function __construct() {
- $this->user = new UserModel();
- }
- //被动依赖
- function __construct(UserModel $user) {
- $this->user = $user;
- }
参考
是 Laravel 的核心设计模式,对于 laravel 的应用和理解是非常有必要深入学习的!
IOC 思想实现了高度解耦,那么,问题来了,如何管理这些分散的模块呢?这就是容器的任务了!
可以想象成,在 IOC 容器中,装着(注册)很多模块。当用户需要一个模块的时候,可以从中拿出来。当提取的模块依赖另一个模块的时候,容器会自动注入,再返回给用户(反射机制实现)。
是不是碉堡了?大批互相依赖的模块被完美解耦并统一管理了!
假设模块一多,那么容器不是越来越大?每次加载,岂不是加载好久? 能不能弄一条管子,连接着模块,插在容器上,需要再通过管道获取呢?这样子,容器只是装着管头而已,就不怕被撑大了!
这条管子就是 。
服务提供者本身也是一个类,不过这个类只有启动和注册两个函数。
- /**
- * Bootstrap the application services.
- *
- * @return void
- */
- public function boot()
- {
- //
- }
- /**
- * Register the application services.
- *
- * @return void
- */
- public function register()
- {
- //绑定到容器
- $this->app->singleton(
- 'Riak\Contracts\Connection',
- function ($app) {
- return new Connection($app['config']['riak']);
- }
- );
- }
服务提供者在 config/app.php 中配置,laravel 自动注册到容器中。
- 'providers' => [
- /*
- * Laravel Framework Service Providers...
- */
- Illuminate\Auth\AuthServiceProvider::class,
- Illuminate\Broadcasting\BroadcastServiceProvider::class,
- ...
- /*
- * Application Service Providers...
- */
- app\Providers\AppServiceProvider::class,
- app\Providers\AuthServiceProvider::class,
- ...
- ]
程序猿总是偷懒的,每次要模块,都要去容器里面拿,多麻烦啊!找个人代拿行不?这送货小哥就叫 Facade 门面。文档中叫静态代理。
送货小哥都是在 config/app.php 中注册的。
- 'aliases' => [
- 'App' => Illuminate\Support\Facades\App::class,
- 'Config' => Illuminate\Support\Facades\Config::class,
- 'Cookie' => Illuminate\Support\Facades\Cookie::class,
- 'Crypt' => Illuminate\Support\Facades\Crypt::class,
- 'DB' => Illuminate\Support\Facades\DB::class,
- 'Route' => Illuminate\Support\Facades\Route::class,
- ...
- ],
查看 Illuminate\Support\Facades\Route 代码,可以发现只有 getAccessFacade()方法,这就是交代送啥货的函数,继承了 Facade 这个小哥基类。
- class Route extends Facade
- {
- /**
- * Get the registered name of the component.
- *
- * @return string
- */
- protected static function getFacadeAccessor()
- {
- return 'router';
- }
- }
注册了 Facade 门面后,就可以在任意地方使用了!
文档有详细的使用方式 。
不难发现,在引导程序开始初始化的时候,也就是在 boostrap\app.php 文件,里面一来就 new 了一个 Illuminate\Foundation\Application。下面分别注册了 Http\Kernel、Console\Kernel、Exceptions\Handler 等。
这里可以这么理解,new 一个 Application,可以看作是创造了一个空间,这个空间初始化的时候,就会为自己注入一个容器,也就是在空间中放了一个容器。
在 Illuminate\Foundation\Application.php 中的 registerBaseBindings() 函数可以查看到容器注入源码。
至于 kernel,可以看成是这个空间的工人,有各种各样的工人,每个工人都有自己的工作。好比 HttpKernel,负责处理 http 请求以及控制整个请求流程。
来源: