«

php laravel 依赖注入,自动注入,接口绑定实现类

时间:2024-3-11 15:13     作者:xiang     分类: php


<?php

namespace App\Http\Controllers;

use App\Service\IComputerService;
use App\Validator\IValidator;
use Illuminate\Http\Request;

class IndexController extends Controller
{
    private IComputerService $ComputerService;
    private IValidator $Validator;

    public function __construct(IComputerService $ComputerService, IValidator $Validator)
    {
        $this->ComputerService = $ComputerService;
        $this->Validator = $Validator;
    }

    public function index(Request $request)
    {
        $param = $this->Validator->check($request);

        $res = $this->ComputerService->index($param['per_page']);

        return response()->json($res);
    }
}

以上是一个控制器,

  private IComputerService $ComputerService; 

以上是业务逻辑层,限定IComputerService接口

  <?php

namespace App\Service;

interface IComputerService{
    public function index($per_page);
}

以上是一个IComputerService 业务逻辑层的接口


 public function __construct(IComputerService $ComputerService, IValidator $Validator)
    {
        $this->ComputerService = $ComputerService;
        $this->Validator = $Validator;
    }

以上是把$ComputerService注入到IndexController

那么在哪里自动注入到服务容器呢?

<?php

namespace App\Providers;

use App\Http\Controllers\IndexController;
use App\Service\IComputerService;
use App\Service\impl\ComputerServiceImpl;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    //    $this->app->bind(IComputerService::class, ComputerServiceImpl::class);

        $this->app->when(IndexController::class)
            ->needs(IComputerService::class)
            ->give(ComputerServiceImpl::class);
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        //
    }
}

以上代码是声明IndexController如果需要注入IComputerService接口,会自动调用ComputerServiceImpl实现类.

这样就可以实现代码解偶,符合依赖倒置原则,Dependency inversion principle,抽象不应依赖于细节,细节应依赖于抽象。

控制器如果要替换业务逻辑层即service层,不需要修改控制器的代码,只要新增和替换IComputerService 接口的实现类.

和在服务注册AppServiceProvider里修改一下 对应的实现类就可以了.

这里还有问题要注意.就是IComputerService没有指定返回数据的类型或者对象类型.这样不方便以后的修改或者替换.