六星教育-laravle6.0-IOC-DI浅谈

时间:2019-10-31
本文章向大家介绍六星教育-laravle6.0-IOC-DI浅谈,主要包括六星教育-laravle6.0-IOC-DI浅谈使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.什么是IOC,DI

IOC(Inversion of Control)控制反转:ioc意味着,你将自己设计好的对象交给容器来控制,而不是传统的在你的对象内部直接控制。比如:

人 操控 手机 做一些事情;  

手机 实现人工智能,手机自己可以做一些事情。

DI(Dependency Injection)依赖注入:di意味着,在程序运行的过程中,动态的向某个对象提供它所需要的其他对象(换句话说就是:将依赖的对象分离,当依赖的对象需要使用这些依赖关系的时候,依赖关系才会被建立)。比如:

异地恋的关系:当男孩和女孩想要在一起的时候,可以通过开车建立联系到一起,约会吃饭做一些事;没有建立联系的时候是彼此独立的。

解耦:IOC,DI一定程度解耦程序

拓展:AOP(Aspect Oriented Programming)面向切面编程:是OOP的延续,将系统中非核心的业务提取出来,单独处理。

2.IOC的本质是?

laravel6.0中 IOC的本质就是一个容器数组。如下:

$array = [

  'app' => 'Application::class', //闭包

  '标识'=>'类'

]

依赖注入:就是把新的标识 , 新的类  新增到容器中。

3.浅谈laravel6.0中原生的IOC

将定义的类注入到容器[数组]中,当需要用到该类时,让容器构造出一个自己需要的类的实例,返回具体容器构造出来的实例来使用。
依赖注入:在容器类中 调用闭包函数 传入类名,具体信息 new类的对象 保存在容器数组$bindings[]中。
控制反转:需要某个类的对象,传入类名[别名,参数] 解析获取到该类的具体实例。

4.浅谈laravel的核心类container

/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php 
$bindings[] 容器数组:所有注入的类保存在该数组中
绑定类到容器数组
public function bind($abstract, $concrete = null, $shared = false)
{
$this->dropStaleInstances($abstract); //删除旧实例和别名(已经绑定的类)
// 没有具体的类型给出,则设置具体类型的抽象类型。
if (is_null($concrete)) {
$concrete = $abstract;
}
//如果不是闭包Closure,这意味着它仅仅是被绑定到这个容器抽象类型
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared'); //把一个抽象类注入到容器中
// 如果抽象类型是在该容器中已经解析,触发反弹侦测,获取回调解析的对象副本
if ($this->resolved($abstract)) {
$this->rebound($abstract);
}
}
获取绑定(注入)类时需要的闭包
protected function getClosure($abstract, $concrete)
{
//返回闭包函数解析的 实例
  return function ($container, $parameters = []) use ($abstract, $concrete) {
//如果要注入的abstract concrete类型具体是抽象类 则回调注入$container->build($concrete);
     if ($abstract == $concrete) {
return $container->build($concrete);
}
//解析容器中给定的类型
return $container->resolve(
$concrete, $parameters, $raiseEvents = false
);
};
}

解析容器中给定的类型
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{
$abstract = $this->getAlias($abstract); //获取一个可用的抽象类的别名

$needsContextualBuild = ! empty($parameters) || ! is_null(
$this->getContextualConcrete($abstract)//获取具体抽象内容
);

//
if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
return $this->instances[$abstract];//共享实例
}

$this->with[] = $parameters; //覆盖堆栈的参数

$concrete = $this->getConcrete($abstract); //获取给定抽象的具体类型

// 递归绑定注册具体的实例,以致于所有嵌套的依赖也被解析
if ($this->isBuildable($concrete, $abstract)) {
$object = $this->build($concrete);
} else {
$object = $this->make($concrete);
}

// 获取给定类型扩展回调
foreach ($this->getExtenders($abstract) as $extender) {
$object = $extender($object, $this);
}

// 共享实例
if ($this->isShared($abstract) && ! $needsContextualBuild) {
$this->instances[$abstract] = $object;
}

if ($raiseEvents) {
$this->fireResolvingCallbacks($abstract, $object);
}

// 返回之前设置标志为真
$this->resolved[$abstract] = true;
  // 移除覆盖当前版本堆栈参数,$with[] 覆盖堆栈参数数组
array_pop($this->with);
  // 返回完全构造的具体实例
return $object;
}

原文地址:https://www.cnblogs.com/dreamofprovence/p/11771007.html