Search code examples
adapterlaravel-5.5construct

laravel factory adapter pattern


I'm implementing adapter pattern on Laravel 5.5.

Questions: I have already using DI in adapter. Why errors show that too few arguments have been passed in constructor. The constructor should be created automatically, right?

The error

enter image description here

Here is my controller.

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\ExcelService;

class ExcelController extends Controller
{
   public function __construct(ExcelService $excelService)
   {
      $this->excelService = $excelService;
   }

   public function export(Request $request)
   {
      $excel = $this->excelService->export($request->get('sheet_name'), 
      $request->except('_token', 'sheet_name'));

      return $excel;
   }

   public function import(Request $request)
   {

   }
}

Here is my service.

<?php

namespace App\Services;

class ExcelService
{
   private $excel;
   private $factory;

   public function __construct(ExcelFactory $factory)
   {
        $this->factory = $factory;
   }

   public function export(String $sheet_name, array $date_range)
   {
      $this->excel = $this->factory->create($sheet_name);
      $this->excel->export($sheet_name, $date_range);
   }

   public function import()
   {

   }
}

Here is my factory.

<?php

namespace App\Services;

class ExcelFactory
{
  /**
   * 建立 adapter
   * @return Excel
   */
   public static function create(String $sheet_name): Excel
   {
    $lut = [
        'member' => MemberExcelAdapter::class,
    ];

    $className = collect($lut)
        ->get($sheet_name, MemberExcelAdapter::class);

    return new $className;
   }
}

Here is my interface.

<?php

namespace App\Services;

interface ExcelInterface
{
  /**
   * 匯出資料
   * @param String $list_name 
   */
   public function export(String $list_name, array $date_range);

  /**
   * 
   */
  public function import();
}

Here is my adapter.

<?php
namespace App\Services;

use App\Excel\MemberExcel;

class MemberExcelAdapter implements ExcelInterface
{
   /** @var MemberExcel */
   private $excel;

   /**
   * MemberExcelAdapter constructor
   * @param MemberExcel $member_excel
   */
   public function __construct(MemberExcel $member_excel)
   {
     $this->excel = $this->member_excel;
    }

   public function export(String $list_name, array $date_range)
   {
     return $this->excel->export($list_name, $date_range);
   }

   public function import()
   {

   }
}

Solution

  • You should bind your interfaces to laravel container for auto laravel resolve dependency.

    referr to this: https://laravel.com/docs/5.6/container#automatic-injection and this https://laravel.com/docs/5.6/contracts