简体   繁体   English

在 controller 上注入服务的正确方法

[英]Proper way to inject a service on a controller

I am implementing the Repository Pattern (service) in a Laravel application and I have some doubts about the usage of interfaces with these services.我在 Laravel 应用程序中实现存储库模式(服务),我对这些服务的接口使用有一些疑问。

I have created an interface called CRUD (code bellow) to serve as a way to always keep the same names for the services that are going to implement CRUD methods.我已经创建了一个名为CRUD的接口(代码如下),作为一种方式来始终为将要实现 CRUD 方法的服务保持相同的名称。

<?php

namespace App\Interfaces;

interface CRUD
{
  public function create(array $data);
  public function update(int $id, array $data);
  public function delete(string $ids);
};

Bellow there's an example of how I call my service and the service itself, and that's where my doubts are.下面是我如何调用我的服务和服务本身的示例,这就是我的疑虑所在。 Usually I'll see people witing an interface for each service and demanding the controller to have injected an objet of that type.通常我会看到人们为每个服务设置一个接口,并要求 controller 注入该类型的对象。 Because of that, people will have to bind a specific type (interface) to the controller. It seems redundant and thus I simply passed the service I need.因此,人们必须将特定类型(接口)绑定到 controller。这似乎是多余的,因此我只是通过了我需要的服务。

Now, is this ok or I should pass the CRUD interface to the controller in this case?现在,这样可以吗?在这种情况下,我应该将 CRUD 接口传递给 controller 吗? Or should I even create another interface specifically for each service?或者我是否应该专门为每项服务创建另一个接口?

<?php

namespace App\Http\Controllers\Cms;

use App\Http\Controllers\Controller;
use App\Http\Requests\GroupRequest;
use App\Models\Group;
use App\Services\GroupsService;
use Illuminate\Http\Request;

class GroupsController extends Controller
{
  private $service;

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

  public function store(GroupRequest $request)
  {
    $result = $this->service->create($request->all());
    return redirect()->back()->with('response', $result);
  }

  public function update(GroupRequest $request, $id)
  {
    $result = $this->service->update($id, $request->all());
    return redirect()->back()->with('response', $result);
  }

  public function destroy($groups_id)
  {
    $result = $this->service->delete($groups_id);
    return redirect()->back()->with('response', $result);
  }
}
<?php

namespace App\Services;

use App\Models\Group;
use App\Interfaces\CRUD;
use Exception;

class GroupsService implements CRUD
{
  public function listAll()
  {
    return Group::all();
  }

  public function create(array $data)
  {
    $modules_id = array_pop($data);

    $group = Group::create($data);
    $group->modules()->attach($modules_id);

    return cms_response(trans('cms.groups.success_create'));
  }

  public function update(int $id, array $data)
  {
    try {
      $modules_ids = $data['modules'];
      unset($data['modules']);
      $group = $this->__findOrFail($id);

      $group->update($data);
      $group->modules()->sync($modules_ids);

      return cms_response(trans('cms.groups.success_update'));
    } catch (\Throwable $th) {
      return cms_response($th->getMessage(), false, 400);
    }
  }


  public function delete(string $ids)
  {
    Group::whereIn('id', json_decode($ids))->delete();
    return cms_response(trans('cms.groups.success_delete'));
  }

  private function __findOrFail(int $id)
  {
    $group = Group::find($id);
    if ($group instanceof Group) {
      return $group;
    }
    throw new Exception(trans('cms.groups.error_not_found'));
  }
}

If you want to use Repository Design Patteren You have to create seprate Interface for each service accroing to SOLID Principle.如果你想使用存储库设计模式,你必须为每个服务创建单独的接口,以符合 SOLID 原则。 You have to create custom service provider and register your interface and service class and then inject interface in construtor of controller. You can also follow below article.您必须创建自定义服务提供者并注册您的接口和服务 class,然后在 controller 的构造函数中注入接口。您也可以按照下面的文章进行操作。 https://itnext.io/repository-design-pattern-done-right-in-laravel-d177b5fa75d4 https://itnext.io/repository-design-pattern-done-right-in-laravel-d177b5fa75d4

I did something with repo pattern in laravel 8 you might be interested:我在 laravel 中使用回购模式做了一些事情 8 你可能会感兴趣:

thats how i did it:我就是这样做的:

first of all, you need to implement a provider首先,你需要实现一个提供者

in this file i created the binding:在这个文件中我创建了绑定:

App\ProvidersRepositoryServiceProvider.php

use App\Interfaces\EventStreamRepositoryInterface;
use App\Repositories\EventStreamRepository;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{

 public function register()
    {
        $this->app->bind(EventStreamRepositoryInterface::class, EventStreamRepository::class);
    }

}

then in file:然后在文件中:

app\Interfaces\EventStreamRepositoryInterface.php

interface EventStreamRepositoryInterface {
    public function index();
    public function create( Request $request );
    public function delete($id);
}

in file:在文件中:

App\Repositories\EventStreamRepository.php App\Repositories\EventStreamRepository.php

class EventStreamRepository implements EventStreamRepositoryInterface{

public function index()
{
  return EventStream::with(['sessions'])
        ->where([ ["status", "=", 1] ] )
        ->orderBy('created_at', 'DESC')
        ->get();
}


public function create(Request $request)
{
    request()->validate([
        "data1"      => "required",
        "data2"      => "required"
    ]);

    $EventStream = EventStream::create([
        'data1'      => request("data1"),
        'data2'      => request('data2')
    ]);

    return $EventStream->id;
}

public function delete($id)
{
  return EventStream::where('id', $id)->delete();
}

}

in file:在文件中:

App\Http\Controllers\EventStreamController.php应用\Http\Controllers\EventStreamController.php

use App\Interfaces\EventStreamRepositoryInterface;
class EventStreamController extends Controller{

private EventStreamRepositoryInterface $eventStreamRepository;

public function __construct(EventStreamRepositoryInterface $eventStreamRepository)
{
    $this->eventStreamRepository = $eventStreamRepository;
}

 public function index():JsonResponse
{
  $this->eventStreamRepository->index();
}


    public function store(Request $request ):JsonResponse
    {
     $this->eventStreamRepository->create($request);
    }

 public function destroy($id):JsonResponse
    {
        $this->eventStreamRepository->delete($id);   
    }

}//class

note: i think i removed all unnecessary -validations- and -returns- in controller for better reading.注意:我想我删除了 controller 中所有不必要的-validations--returns-以便更好地阅读。

Hope it helps!!希望能帮助到你!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM