1

在我的应用程序中,我有一个名为“LogService”的服务来记录事件和其他项目。我基本上需要在每个控制器上使用它来记录用户的事件。不必在每个控制器中实例化这个服务,我有两个想法来完成这个。

选项 1:将服务绑定到 IoC,然后以这种方式解析它

选项 2:创建一个包含服务的主类,然后为其他类扩展它,以便它们与已经绑定的服务一起提供

我对这些方法中的每一种都有疑问:

选项1:这甚至可能吗?如果是这样,它会被称为“App::make()”吗?这种方式似乎不太适合IDE

选项 2:我过去做过这种事情,但 PHPStorm 似乎无法识别来自父对象的服务,因为它是由“App::make()”实例化的,而不是通过常规依赖注入。

最好的行动方案是什么?

谢谢!

4

1 回答 1

1

你可以有两种方式,我认为最简洁的方式是:

1)有一个描述你的类的接口,让我们称之为LogServiceInterface

2)创建一个实例化您的类的服务提供者,如下所示:

<?php

 namespace App\Providers;

 use Illuminate\Support\ServiceProvider;

 class LoggerServiceProvider extends ServiceProvider
 {
     /**
      * Register bindings in the container.
      *
      * @return void
      */
     public function register()
     {
         $this->app->bind(LogServiceInterface::class, function($app)
         {
             return new LogService();
         });
     }
  }

config/app.ph3) 在文件中注册此服务提供者:

'providers' => [
    // Other Service Providers

    App\Providers\LoggerServiceProvider::class,
],

LoggerServiceInterface4)现在,在控制器中,您可以请求直接在构造函数中实现的东西的实例:

(一些控制器):

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Repositories\OrderRepository;

class OrdersController extends Controller {

    /**
     * The logger service.
     * @var LoggerServiceInterface $loggerService
     */
    protected $loggerService;

    /**
     * Create a controller instance.
     *
     * @param  OrderRepository  $orders
     * @return void
     */
    public function __construct(LoggerServiceInterface $loggerService)
    {
        $this->loggerService = $loggerService;
    }

    /**
     * Show all of the orders.
     *
     * @return Response
     */
    public function index()
    {
        // $this->loggerService will be an instance of your LoggerService class that 
        // is instantiated in your service provider
    }

}

这样,您就可以轻松地快速更改服务的实现,而且,Phpstorm 可以非常轻松地处理这个问题。

您仍然可以使用app()->make()来获取您的服务实例。然而,这不会被 Phpstorm 自动拾取。但是您可以帮助它理解,您需要做的就是使用@var注释,请参阅:

/**
 * @var LoggerServiceInterface $logger
 */
 $logger = app()->make(LoggerServiceInterface::class);

That way, Phpstorm will know what to expect from that $logger object.
于 2019-02-12T15:19:45.063 回答