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

你为"某些人的问题”注入了类的依赖关系。在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. Hibernate HQL注入与防御(ctf实例)

    遇到一个hql注入ctf题    这里总结下java中Hibernate HQL的注入问题. 0x01 关于HQL注入 Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码) ...

  2. 后门免杀工具-Backdoor-factory

    水一水最近玩的工具 弄dll注入的时候用到的 介绍这款老工具 免杀效果一般..但是简单实用  目录: 0x01 backdoor-factory简介 0x02 特点功能 0x03 具体参数使用 PS: ...

  3. [NOIp2014] luogu P1351 联合权值

    哎我博 4 了. 题目描述 无向连通图 GGG 有 nnn 个点,n−1n−1n−1 条边.点从 111 到 nnn 依次编号,编号为 iii 的点的权值为 WiW_iWi​,每条边的长度均为 111 ...

  4. stm32cubeMX配置LWIP

    MCU:stm32f769NIHx  PHY:LAN8742A LWIP_VERSION:2.0.3 1.配置RCC,串口(printf debug log) (1)开启RCC,配置时钟系统 图1.1 ...

  5. Windows 批量修改文件后缀名

    利用ren 文件名替换命令 for循环去批处理 @echo off for %%m in (*) do ( if not "%%m"=="temp.bat"( ...

  6. Unity - HasExitTime用法

    本文详细分析了AnimatorController中动画切换过渡问题,即Translation过渡及hasExitTime的问题.方法为对实际项目中的所有情况进行分类,规划逻辑图,可视化分析解决这些问 ...

  7. redis系列之------对象

    前言 Redis 并没有直接使用数据结构来实现键值对数据库, 而是基于这些数据结构创建了一个对象系统, 这个系统包含字符串对象.列表对象.哈希对象.集合对象和有序集合对象这五种类型的对象, 每种对象都 ...

  8. django-表单之模型表单渲染(六)

    class StudentForms(forms.ModelForm): formats=[ '%Y-%m-%d', '%m/%d/%Y', ] birthday = forms.DateField( ...

  9. ArcGIS Engine空间分析之缓冲区分析的实现

    缓冲分析(BufferAnalysis)的结果是一个面状要素——即缓冲要素,点状要素.线状要素和面状要素,被缓冲分析功能处理过之后,它们的周围产生一个缓冲区域,该区域即新产生的面状要素. 在缓冲方向上 ...

  10. Java基础系列二:Java泛型

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 一.泛型概述 1.定 ...