这篇文章主要讲解了“laravel中的Service Container的概念及使用方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“laravel中的Service Container的概念及使用方法”吧!
The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection.
从Laravel官方文档对于Service Container的解释可以看出,它的作用就是帮助我们管理和进行依赖注入的。
在《依赖注入》中,我们看到使用依赖注入可以极大的降低代码的耦合度,但是也带来了一个缺点,就是需要自己管理注入的对象。
如果一个组件有很多依赖,我们需要创建多个参数的setter方法来传递依赖关系,或者建立一个多个参数的构造函数来传递它们,另外在使用组件前还要每次都创建依赖,这让我们的代码像这样不易维护。
所以为依赖实例提供一个容器(Service Container),就是一个实用而且优雅的方法。
比如下面是laravel的入口文件(已去掉注释):
// public/index.php
<?php
require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
// bootstrap/app.php
<?php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
return $app;
首先看bootstrap/app.php
,其中$app
是Illuminate\Foundation\Application
的一个实例,而Illuminate\Foundation\Application
类继承自Container,所以$app
实际上就是一个Service Container。
然后下面的三个singleton方法定义了当依赖Illuminate\Contracts\Http\Kernel
、Illuminate\Contracts\Console\Kernel
、Illuminate\Contracts\Debug\ExceptionHandler
这三个接口时,注入哪个类的单例。
然后看public/index.php
,其中的make方法实际上就是用Service Container来new一个Illuminate\Contracts\Http\Kernel
实例,跟普通new的区别就是会把他的依赖自动注入进去。
是不是很简洁?
其实不单是Laravel,像Yii2、Phalcon等框架都通过实现容器来管理依赖注入。
既然是一个容器,无非就是两个事,往里放东西和往外取东西,对应到Service Container就是绑定(Binding)和解析(Resolving)。
在Laravel的Service Provider中,可以通过$this->app
获取容器,除此之外,还可以使用app()
来获取容器。
如果在Laravel外使用Service Container,直接new一个Illuminate\Container\Container
就可以获得容器了。
以下都用$container代表获取到的容器。
绑定返回接口的实例
//使用闭包
$container->bind('BarInterface', function(){
return new Bar();
});
//或者使用字符串
$container->bind('FooInterface', 'Foo');
绑定单例
singletion 方法绑定一个只会被解析一次的类或接口至容器中,且后面的调用都会从容器中返回相同的实例:
$container->singleton('BarInterface', function(){
return new Bar();
});
绑定实例
你也可以使用 instance 方法,绑定一个已经存在的对象实例至容器中。后面的调用都会从容器中返回指定的实例:
$bar = new Bar();
$bar->setSomething(new Something);
$container->instance('Bar', $bar);
情境绑定
有时候,你可能有两个类使用到相同接口,但你希望每个类都能注入不同实现。
$container->when('Man')
->needs('PartnerInterface')
->give('Woman');
$container->when('Woman')
->needs('PartnerInterface')
->give('Man');
标记
有些时候,可能需要解析某个「分类」下的所有绑定。
$container->bind('Father', function () {
//
});
$container->bind('Mother', function () {
//
});
$container->bind('Daughter', function () {
//
});
$container->bind('Son', function () {
//
});
$container->tag(['Father', 'Mother', 'Daughter', 'Son'], 'familyMembers');
$container->bind('Family', function ($container) {
return new Family($container->tagged('familyMembers'));
});
make方法
$foo = $container->make('Foo');
数组方法
$bar = $container['Bar'];
解析被标记绑定
$familyMembers = $container->tagged('familyMembers');
foreach ($familyMembers as $inpidual) {
$inpidual->doSomething();
}
每当服务容器解析一个对象时就会触发事件。你可以使用 resolving 方法监听这个事件。
$container->resolving(function ($object, $container) {
// 当容器解析任何类型的对象时会被调用...
});
$container->resolving('Foo', function (Foo $foo, $container) {
// 当容器解析「Foo」类型的对象时会被调用...
});
感谢各位的阅读,以上就是“laravel中的Service Container的概念及使用方法”的内容了,经过本文的学习后,相信大家对laravel中的Service Container的概念及使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。