经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
PHP 从另一个角度来分析 Laravel 框架的依赖注入功能
来源:cnblogs  作者:程序媛的明天  时间:2019/11/6 8:52:39  对本文有异议
从根本上说,依赖注入不是让对象创建一个依赖关系,也不是让工厂对象去创建对象,而是将所需的依赖变成一个外部对象,使之成为一个"某些人的问题”

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

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

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

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

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

 

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

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

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

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

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

 

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

  1. 1 <?php
  2. 2 namespace App\Providers;
  3. 3 use Illuminate\Support\ServiceProvider;
  4. 4 class MyServiceProvider extends ServiceProvider
  5. 5 {
  6. 6 public function register()
  7. 7 {
  8. 8 $this->app->singleton(\My\Service::class, function ($app) {
  9. 9 return new \My\Service($app->make('My\AnotherService'));
  10. 10 });
  11. 11 }
  12. 12 }

 

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

  1. 1 <?php
  2. 2 namespace App\Http\Controllers;
  3. 3 use App\User;
  4. 4 use App\Http\Controllers\Controller;
  5. 5 class MyController extends Controller
  6. 6 {
  7. 7 protected $myService;
  8. 8 public function __construct(\My\Service $myService)
  9. 9 {
  10. 10 $this->myService = $myService;
  11. 11 }
  12. 12 // .. 方法
  13. 13 }

 

真实的例子

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

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

 

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

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

 

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

结论

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

原文链接:http://www.cnblogs.com/a609251438/p/11801070.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号