Laravel项目的服务类实现

此包的官方仓库似乎已不存在,因此包已被冻结。

0.3.0 2019-09-03 21:11 UTC

This package is auto-updated.

Last update: 2022-05-04 03:17:34 UTC


README

Laravel项目的服务类实现。

Latest Stable Version Build Status Quality Score Total Downloads

Perfect Oblivion

免责声明

PerfectOblivion命名空间下的包旨在提供一些我更喜欢不从头开始复制的功能。这里没有什么突破性的东西。

灵感

PerfectOblivion服务包解决了我长期以来的一些痒点。我经常使用单个操作控制器,结合响应者类和服务类来收集/处理数据。服务类是模仿Laravel的jobs/dispatcher。我更喜欢在控制器之外处理大部分领域工作。这并不是太多工作,并且允许在HTTP层之外使用这种逻辑。

示例

namespace App\Http\Controllers\Tasks;

use App\Http\Controllers\Controller;
use App\Services\StoreNewTaskService;
use App\Http\Requests\StoreNewTaskRequest;
use App\Http\Responders\Task\StoreResponder;
use PerfectOblivion\Services\Traits\CallsServices; // the trait could be added to your parent Controller class

class Store extends Controller
{
    use CallsServices;

    /**
     * The service used to store a new task.
     *
     * @var \App\Http\Responders\Task\StoreResponder
     */
    private $responder;

    /**
     * Construct a new Store controller.
     *
     * @param  \App\Http\Responders\Task\StoreResponder  $responder
     */
    public function __construct(StoreResponder $responder)
    {
        $this->responder = $responder;
    }

    /**
     * Handle the task store action.
     *
     * @param  \App\Http\Requests\StoreTaskRequest  $request
     *
     * @return \Illuminate\Http\Response
     */
    public function __invoke(StoreTaskRequest $request)
    {
        $task = $this->call(StoreNewTaskService::class, ($request->validated()));
        // or
        // StoreNewTaskService::call($request->validated());

        return $this->responder->withPayload($task);
    }
}

我的控制器只是将脏活留给服务处理,然后使用响应者发送响应。一个非常干净的方法。

安装

您可以通过composer安装此包。从您的项目目录中,在您的终端中输入

composer require perfect-oblivion/services

在Laravel > 5.6.0中,ServiceProvider将自动检测并注册。如果您使用的是较旧版本的Laravel,请将包服务提供者添加到您的config/app.php文件中的'providers'数组中

'providers' => [
    //...
    PerfectOblivion\Services\ServicesServiceProvider::class,
    //...
];

包配置

如果您想更改任何包配置选项,请在您的终端中运行以下命令

php artisan vendor:publish

并选择'PerfectOblivion/Services'选项。

这将复制包配置(service-classes.php)到您的'config'文件夹。请参阅以下配置文件,以获取所有可用选项

return [
    /*
    |--------------------------------------------------------------------------
    | Namespaces
    |--------------------------------------------------------------------------
    |
    | Set the namespace for Service classes.
    |
    */
    'namespace' => 'Services',

    /*
    |--------------------------------------------------------------------------
    | Suffixes
    |--------------------------------------------------------------------------
    |
    | Set the suffix for the Service classes.
    |
    */
    'suffix' => 'Service',

    /*
    |--------------------------------------------------------------------------
    | Method Name
    |--------------------------------------------------------------------------
    |
    | Set the method name for handling services.
    |
     */
    'method' => 'run',

    /*
    |--------------------------------------------------------------------------
    | Duplicate Suffixes
    |--------------------------------------------------------------------------
    |
    | If you have a Service suffix set in the config and try to generate a Service that also includes the suffix,
    | the package will recognize this duplication and rename the Service to remove the extra suffix.
    | This is the default behavior. To override and allow the duplication, change to false.
    |
    */
    'override_duplicate_suffix' => true,
];

使用

一旦安装了包并复制了配置(可选),您就可以开始生成您的服务。

生成服务类

从您的项目目录内部,在您的终端中运行

php artisan adr:service StoreNewTask

基于上述配置选项,这将创建一个'App\Services\StoreNewTaskService'类。

注意,默认情况下,当您调用服务时将调用'run'方法。您可以在配置文件中更改此方法名。

示例服务类

// Service Class
namespace App\Services;

use App\Models\Repositories\TaskRepository;
use PerfectOblivion\Common\Payloads\Payload;

class StoreNewTaskService
{
    /**
     * The parameters for building a new Task.
     *
     * @var array
     */
    public $repo;

    /**
     * Construct a new StoreNewTaskService.
     *
     * @param  \App\Models\Repositories\TaskRepository  $repo
     */
    public function __construct(TaskRepository $repo)
    {
        $this->repo = $repo;
    }

    /**
     * Handle the call to the service.
     *
     * @param  mixed  $params
     *
     * @return mixed
     */
    public function run($params)
    {
        return $this->repo->create($params);
    }
}

如上例所示,只需在服务构造函数中对依赖项进行类型提示。这些依赖项将由Laravel从容器中解析。当调用服务时传递的任何参数都将传递给服务的"run"方法。

如何调用服务

目前,调用服务有多种选择。

首先,您可以使用包含的 'CallsServices' 特性

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\StoreNewTaskService;
use PerfectOblivion\Services\Traits\CallsServices;

class StoreTaskController extends Controller
{
    use CallsServices;

    public function store(Request $request)
    {
        $task = $this->call(StoreNewTaskService::class, ($request->all()));

        return view('tasks.show', ['task' => $task]);
    }
}

下一个选项是通过依赖注入包含 ServiceCaller,然后使用 "call" 方法

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\StoreNewTaskService;
use PerfectOblivion\Services\ServiceCaller;

class StoreTaskController extends Controllerr
{
    private $caller;

    public function __construct(ServiceCaller $caller)
    {
        $this->caller = $caller;
    }

    public function store(Request $request)
    {
        $task = $this->caller->call(StoreNewTaskService::class, ($request->all()));

        return view('tasks.show', ['task' => $task]);
    }
}

接下来,服务具有自我调用的能力

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\StoreNewTaskService;

class StoreTaskController extends Controller
{
    public function store(Request $request)
    {
        $task = StoreNewTaskService::call($request->all());

        return view('tasks.show', ['task' => $task]);
    }
}

最后,可能是最常见的方法,是将 Service 类注入到您的 Controller 或 Action 中,并调用 'run' 方法

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\StoreNewTaskService;

class StoreTaskController extends Controllerr
{
    private $service;

    public function __construct(StoreNewTaskService $service)
    {
        $this->service = $service;
    }

    public function store(Request $request)
    {
        $task = $this->service->run($request->all());

        return view('tasks.show', ['task' => $task]);
    }
}

排队服务调用

如果您需要排队服务而不是立即调用它,请使用 queue() 方法而不是 call() 方法。包将在幕后处理队列设置。不需要更改 Service 类的构建方式。只需将您的 call() 调用替换为 queue()。所有排队的服务都将带有 'queued-service' 的名称。

测试

composer test

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

有关详细信息,请参阅 CONTRIBUTING

安全

如果您发现任何安全相关的问题,请通过电子邮件 clay@phpstage.com 而不是使用问题跟踪器。

路线图

我们计划很快开始工作于灵活性/配置,以及发布一个无框架版本的包。

鸣谢

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件