zoukankan      html  css  js  c++  java
  • PHP 从另一个角度来分析 Laravel 框架的依赖注入功能

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

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

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

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

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

     1 <?php
     2 namespace AppHttpControllers;
     3 use AppUser;
     4 use AppRepositoriesUserRepository;
     5 use AppHttpControllersController;
     6 class UserController extends Controller
     7 {
     8     protected $userRepository;
     9     public function __construct(UserRepository $userRepository)
    10     {
    11         $this->userRepository = $userRepository;
    12     }
    13     public function show($id)
    14     {
    15         $user = $this->userRepository->find($id);
    16         return view('user.profile', ['user' => $user]);
    17     }
    18 }

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

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

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

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

    1 <?php
    2 $container->bind('MyService', function($container) {
    3   return new MyService($container->make('MyAnotherService'));
    4 });

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

     1 <?php
     2 namespace AppProviders;
     3 use IlluminateSupportServiceProvider;
     4 class MyServiceProvider extends ServiceProvider
     5 {
     6     public function register()
     7     {
     8         $this->app->singleton(MyService::class, function ($app) {
     9             return new MyService($app->make('MyAnotherService'));
    10         });
    11     }
    12 }

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

     1 <?php
     2 namespace AppHttpControllers;
     3 use AppUser;
     4 use AppHttpControllersController;
     5 class MyController extends Controller
     6 {
     7     protected $myService;
     8     public function __construct(MyService $myService)
     9     {
    10         $this->myService = $myService;
    11     }
    12     // .. 方法
    13 }

    真实的例子

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

     1 <?php
     2 namespace AppHttpControllers;
     3 use AppUser;
     4 use AppHttpControllersController;
     5 use FacebookFacebook;
     6 class FacebookApiAccessController extends Controller
     7 {
     8     protected $facebook;
     9     public function __construct(FacebookFacebook $facebook)
    10     {
    11         $this->facebook = $facebook;
    12     }
    13     //.. action methods here
    14 }

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

    1 <?php
    2 $container->singleton('FacebookFacebook', function() {
    3   return new FacebookFacebook([
    4     'app_id' => config('services.facebook.app_id'),
    5     'app_secret' => config('services.facebook.app_secret'),
    6     'default_graph_version' => 'v2.10',
    7   ]);
    8 });

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

    结论

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

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

  • 相关阅读:
    [calss*="col-"]匹配类名中包含col-的类名,^以col-开头,$以col-结尾
    插件写法之脚本运行环境,mac和window检测
    @media only screen and (max-width:640px)中的问题,响应式布局
    webpack2的配置属性说明entry,output,state,plugins,node,module,context
    npm ERR! missing script: dev 报错解决
    [jshint] 'import' is only available in ES6 (use 'esversion: 6'). (W119) 提示import等ES6语法的jshint错误的,在代码前加一行 /* jshint esversion: 6 */
    Uncaught TypeError: (intermediate value)(...) is not a function 上一个方法结束没有加分号; 代码解析报错
    LeetCode 1. two sum
    redis集群尝试
    服务器搭建私人Git
  • 原文地址:https://www.cnblogs.com/a609251438/p/11801070.html
Copyright © 2011-2022 走看看