从根本上说,依赖注入不是让对象创建一个依赖关系,也不是让工厂对象去创建对象,而是将所需的依赖变成一个外部对象,使之成为一个"某些人的问题”

你为"某些人的问题”注入了类的依赖关系。在Laravel中,这个"某人”是 服务容器 。在Laravel中,服务容器负责通过构造函数注入类的依赖关系。

任何时候,你在一个控制器类中请求一个依赖,这个服务容器负责:

  1. 自动地在构造函数中检测依赖关系
  2. 如果需要构建这个依赖关系
  3. 通过构造函数创建对象形成依赖关系

来看一个非常简单的例子。

 <?php
namespace App\Http\Controllers;
use App\User;
use App\Repositories\UserRepository;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
protected $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function show($id)
{
$user = $this->userRepository->find($id);
return view('user.profile', ['user' => $user]);
}
}

假如,你有一个 UserController 类需要 UserRepository 作为一个构造函数依赖。

  1. 服务容器使用 PHP 的 反射类 来检测,事实 UserRepository 需要被优先解析。
  2. 然后,它构造 UserRepository 实例。
  3. 然后,它构造 UserController 类实例。

依赖关系是如何被解析和注入的,我被很多 Laravel 开发人员不知道这个简单而强大的技术感到迷惑。 这是一个非常强大的技术,它可以被用来解决复杂对象的依赖关系。

如果由于某种原因,您不希望Laravel自动构建一个对象,您还可以通过传递一个可用于创建依赖关系的回调来告诉Laravel Service Container如何构造该对象。

 <?php
$container->bind('My\Service', function($container) {
return new My\Service($container->make('My\AnotherService'));
});

您需要创建一个服务提供商来注册上述服务。

 <?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MyServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(\My\Service::class, function ($app) {
return new \My\Service($app->make('My\AnotherService'));
});
}
}

当 My\Service 需要被解析的时候,负责返回一个对象的回调函数就会被调用。

 <?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class MyController extends Controller
{
protected $myService;
public function __construct(\My\Service $myService)
{
$this->myService = $myService;
}
// .. 方法
}

真实的例子

假设你的应用需要Facebook的PHP SDK来访问Facebook的API,你的控制器就是这样的:

 <?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Facebook\Facebook;
class FacebookApiAccessController extends Controller
{
protected $facebook;
public function __construct(Facebook\Facebook $facebook)
{
$this->facebook = $facebook;
}
//.. action methods here
}

现在,您需要告诉Service Container如何构建 Facebook\Facebook的实例.

 <?php
$container->singleton('Facebook\Facebook', function() {
return new \Facebook\Facebook([
'app_id' => config('services.facebook.app_id'),
'app_secret' => config('services.facebook.app_secret'),
'default_graph_version' => 'v2.10',
]);
});

注意,我已经调用了方法singleton而不是bind。 唯一的区别是用singleton注册的服务被缓存,随后的解析服务调用返回缓存的服务。

结论

依赖注入是一种强大的技术,你可以在 Laravel 中用来简化对象的创建. 默认情况下, Laravel 的服务容器会自动的用反射去检测和解决依赖关系. 但是, 你可以指定回调来解析服务.

phper在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的(点击→)我的官方群677079770

PHP 从另一个角度来分析 Laravel 框架的依赖注入功能的更多相关文章

  1. [ASP.NET Core 3框架揭秘] 依赖注入[4]:一个Mini版的依赖注入框架

    在前面的章节中,我们从纯理论的角度对依赖注入进行了深入论述,我们接下来会对.NET Core依赖注入框架进行单独介绍.为了让读者朋友能够更好地理解.NET Core依赖注入框架的设计与实现,我们按照类 ...

  2. laravel框架中超实用的功能介绍

    本篇文章给大家带来的内容是关于laravel框架中超实用的功能介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 让lumen的dd() dump()像laravel一样优雅 1 c ...

  3. 通过中看不中用的代码分析Ioc容器,依赖注入....

    /** * 通过生产拥有超能力的超人实例 来理解IOC容器 */ //超能力模组接口 interface SuperModuleInterface{ public function activate( ...

  4. TypeC一个微软开发的超简单.NET依赖注入/IoC容器

    控制反转(IoC,Inversion of Control)是由Martin Fowler总结出来的一种设计模式,用来减少代码间的耦合.一般而言,控制反转分为依赖注入(Dependency Injec ...

  5. 自己实现一个IOC(控制翻转,DI依赖注入)容器

    1.新建一个控制台应用程序 TestIOC 2.新增一个 IocFactory类 using System; using System.Collections.Generic; using Syste ...

  6. 在.NET Core中处理一个接口多个不同实现的依赖注入问题

    前言 近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了.博客也就停了一下下. 在.NET Core中处理依赖注入问题时,往往是定义好了一个操作规范的接口,会有N多个基于不同 ...

  7. 【laravel5.*】详解laravel中的依赖注入

    1.下面这个是自定义的类,钉钉扫码登录web 网页授权OAuth2.0,是一个典型的依赖注入参考示例:

  8. Vue.js 源码分析(八) 基础篇 依赖注入 provide/inject组合详解

    先来看看官网的介绍: 简单的说,当组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱.这个就是这对选项要干的事情 provide和 ...

  9. laravel框架实现发送邮件的功能

    1.在config 下的mail.php中配置(配置后面的两个就行了) 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', '7623018 ...

随机推荐

  1. PHP yield代替range生成范围内的数

    <?php function yieldRange($start, $limit, $step) { if ($start == $limit || $step == 0) { return $ ...

  2. [JZOJ100043] 【NOIP2017提高A组模拟7.13】第K小数

    Description 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少. Input 输入文件包含三行. 第一行为 ...

  3. [JZOJ5178]【NOIP2017提高组模拟6.28】So many prefix?

    Description

  4. vue在一个方法执行完后再执行另一个方法

    vue在一个方法执行完后执行另一个方法 用Promise来实现.Promise是ES6的新特性,用于处理异步操作逻辑,用过给Promise添加then和catch函数,处理成功和失败的情况 ES7中新 ...

  5. SpringBoot2.x--入门篇--01--HelloWorld

    很多人说,学习springboot至少需要spring基础,servlet基础等等,笔者不敢苟同.凡是有一定java基础的人,都可以直接学习springboot,当学到原理和源码时,通过查缺补漏的方式 ...

  6. 概念理解:boost::asio::定时器1

    同步定时器 #include <cstdio> #include <iostream> #include <boost/asio.hpp> #include < ...

  7. CSAPP:逆向工程【缓冲区溢出攻击】

    逆向工程[缓冲区溢出攻击] 任务描述 掌握函数调用时的栈帧结构,利用输入缓冲区的溢出漏洞,将攻击代码嵌入当前程序的栈帧中,使程序执行我们所期望的过程. 主要方法 溢出的字符将覆盖栈帧上的数据,会覆盖程 ...

  8. python类中的self

    class User: def walk(self): print(self,"正在慢慢走") # User.walk() # 会报错 TypeError: walk() miss ...

  9. 【Autofac打标签模式】Component和Autowired

    [ Autofac打标签模式]开源DI框架扩展地址: https://github.com/yuzd/Autofac.Annotation/wiki Componet标签把类型注册到DI容器 1. 把 ...

  10. Rancher与ARM深化战略合作,“软硬结合”加速边缘计算时代

    时至今日,许多企业已将边缘计算列为战略目标,对于部分企业而言,边缘计算则已成为它们势在必行的部分.而随着对应用软件和硬件能力的需求不断增长,容器和Kubernetes已发展为边缘计算领域备受瞩目的一项 ...