千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:武汉千锋IT培训  >  技术干货  >  为什么我们需要Laravel IoC容器?

为什么我们需要Laravel IoC容器?

来源:千锋教育
发布人:xqq
时间: 2023-10-14 21:24:27

一、为什么我们需要Laravel IoC容器

因为Laravel 哲学的一个重要组成部分就是 IoC 容器,也可以称为服务容器。它是一个 Laravel 应用的核心部分,因此理解并使用 IoC 容器是我们必须掌握的一项重要技能。IoC 容器是一个非常强大的类管理工具。它可以自动解析类。

首先,我想先谈下依赖反转原则,对它的了解会有助于我们更好地理解 IoC 容器的重要性。

该原则规定:

高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象接口。
抽象接口不应该依赖于具体实现。而具体实现则应该依赖于抽象接口。

一言以蔽之:依赖于抽象而非具体

class MySQLConnection

{

   /**

   * 数据库连接

   */

   public function connect()

   {

      var_dump(‘MYSQL Connection’);

   }

}

class PasswordReminder

{   

    /**

     * @var MySQLConnection

     */

     private $dbConnection;

    public function __construct(MySQLConnection $dbConnection)

    {

      $this->dbConnection = $dbConnection;

    }

}

大家常常会有一个误解,那就是依赖反转就只是依赖注入的另一种说法。但其实二者是不同的。在上面的代码示例中,尽管在 PasswordReminder 类中注入了 MySQLConnection 类,但它还是依赖于 MySQLConnection 类。

然而,高层次模块 PasswordReminder 是不应该依赖于低层次模块 MySQLConnection 的。

如果我们想要把 MySQLConnection 改成 MongoDBConnection,那我们就还得手动修改 PasswordReminder 类构造函数里的依赖。

PasswordReminder 类应该依赖于抽象接口,而非具体类。那我们要怎么做呢?请看下面的例子:

interface ConnectionInterface

{

   public function connect();

}

class DbConnection implements ConnectionInterface

{

 /**

  * 数据库连接

  */

 public function connect()

 {

   var_dump(‘MYSQL Connection’);

 }

}

class PasswordReminder

{

    /**

    * @var DBConnection

    */

    private $dbConnection;

    public function __construct(ConnectionInterface $dbConnection)

    {

      $this->dbConnection = $dbConnection;

    }

}

通过上面的代码,如果我们想把 MySQLConnection 改成 MongoDBConnection,根本不需要去修改 PasswordReminder 类构造函数里的依赖。因为现在 PasswordReminder 类依赖的是接口,而非具体类。

现在我要讲下 IoC 容器里到底发生了什么。我们可以把 IoC 容器简单地理解为就是一个容器,里面装的是类的依赖。

OrderRepositoryInterface 接口:

namespace App\Repositories;

interface OrderRepositoryInterface

{

   public function getAll();

}

DbOrderRepository 类:

namespace App\Repositories;

class DbOrderRepository implements OrderRepositoryInterface

{

  function getAll()

  {

    return ‘Getting all from mysql’;

  }

}

OrdersController 类:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use App\Repositories\OrderRepositoryInterface;

class OrdersController extends Controller

{

    protected $order;

   function __construct(OrderRepositoryInterface $order)

   {

     $this->order = $order;

   }

   public function index()

   {

     dd($this->order->getAll());

     return View::make(orders.index);

   }

}

路由:

Route::resource(‘orders’, ‘OrdersController’);

现在,在浏览器中输入这个地址 

报错了吧,错误的原因是服务容器正在尝试去实例化一个接口,而接口是不能被实例化的。解决这个问题,只需把接口绑定到一个具体的类上。

把下面这行代码加在路由文件里就搞定了:

App::bind(‘App\Repositories\OrderRepositoryInterface’, ‘App\Repositories\DbOrderRepository’)

延伸阅读:

二、控制反转和依赖注入是什么

控制反转,是指对象的创建和配置的控制权从调用方转移给容器。好比在家自己做菜,菜的味道全部由自己控制;去餐馆吃饭,菜的味道则是交由餐馆控制。IoC 容器就担任了餐馆的角色。

有了 IoC 容器,我们可以将对象交由容器管理,交由容器管理后的对象称之为 Bean。调用方不再负责组件的创建,要使用组件时直接获取 Bean 即可:

@Component

public class UserServiceImpl implements UserService{

    @Autowired // 获取 Bean

    private UserDao userDao;

}

调用方只需按照约定声明依赖项,所需要的 Bean 就自动配置完毕了,就好像在调用方外部注入了一个依赖项给其使用,所以这种方式称之为 依赖注入(Dependency Injection,缩写为 DI)。控制反转和依赖注入是一体两面,都是同一种开发模式的表现形式。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

Python10行以内代码能有什么高端操作?

2023-10-14

epoll、poll、select有哪些区别?

2023-10-14

Linux系统有哪些?

2023-10-14

最新文章NEW

html form标签的action属性是什么?

2023-10-14

TCP、UDP的区别是什么,两者在什么时候使用?

2023-10-14

C++中引用和指针有哪些区别?

2023-10-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>