7

Slim Framework 3 を使用して API を作成しています。アプリの構造は、MVCP (モデル、ビュー、コントローラー、プロバイダー) です。

Slim Dependency Inject ですべてのクラスを使用することは可能ですか?

composer を使用して、すべての依存関係を自動ロードしています。

私のディレクトリ構造は次のようになります。

/app
   - controllers/
   - Models/
   - services/
   index.php
/vendor
 composer.json

これが私のcomposer.jsonファイルです。

{
  "require": {
    "slim/slim": "^3.3",
    "monolog/monolog": "^1.19"
  },
  "autoload" : {
    "psr-4" : {
        "Controllers\\" : "app/controllers/",
        "Services\\" : "app/services/",
        "Models\\" : "app/models/"
    }
  }
}

これが私のindex.phpファイルです。繰り返しますが、依存関係はコンポーザーによって自動注入されています

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$container = new \Slim\Container;
$app = new \Slim\App($container);

$app->get('/test/{name}', '\Controllers\PeopleController:getEveryone');

$app->run();

私のコントローラは次のようになります

<?php #controllers/PeopleController.php

namespace Controllers;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;


class PeopleController
{
    protected $peopleService;

    protected $ci;
    protected $request;
    protected $response;

    public function __construct(Container $ci, PeopleService $peopleService)
    {
        $this->peopleService = $peopleService;
        $this->ci = $ci;
    }

    public function getEveryone($request, $response)
    {
        die($request->getAttribute('name'));

        return $this->peopleService->getAllPeoples();
    }
}

私の PeopleService ファイルは次のようになります。

<?php

namespace Services;

use Model\PeopleModel;
use Model\AddressModel;
use Model\AutoModel;


class PeopleService
{
    protected $peopleModel;
    protected $autoModel;
    protected $addressModel;

    public function __construct(PeopleModel $peopleModel, AddressModel $addressModel, AutoModel $autoModel)
    {
        $this->addressModel = $addressModel;
        $this->autoModel = $autoModel;
        $this->peopleModel = $peopleModel;
    }

    public function getAllPeopleInfo()
    {
        $address = $this->addressModel->getAddress();
        $auto = $this->autoModel->getAutoMake();
        $person = $this->peopleModel->getPeople();

        return [
            $person[1], $address[1], $auto[1]
        ];
    }
}

Models/AddressModels.php

<?php

namespace Model;

class AddressModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getAddress()
    {
        return [
            1 => '123 Maple Street',
        ];
    }
}

Models/AutoModel.php

namespace Model;

class AutoModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getAutoMake()
    {
        return [
            1 => 'Honda'
        ];
    }
}

Models/PeopleModel.php

<?php
namespace Model;

class PeopleModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getPeople()
    {
        return [
            1 => 'Bob'
        ];
    }

}

エラー 現在、次のエラーが発生しています。

PHP Catchable fatal error:  Argument 2 passed to Controllers\PeopleController::__construct() must be an instance of Services\PeopleService, none given, called in /var/www/vendor/slim/slim/Slim/CallableResolver.php on line 64 and defined in /var/www/app/controllers/PeopleController.php on line 21

質問 すべてのクラスに依存性を注入するにはどうすればよいですか? Slim の DI Container に自動的に指示する方法はありますか?

4

1 に答える 1

8

呼び出し可能なルートでクラスを参照すると、Slim は DIC にそのクラスを要求します。DIC にそのクラス名の登録がない場合、DIC はクラス自体をインスタンス化し、コンテナーを唯一の引数としてクラスに渡します。

したがって、コントローラーに正しい依存関係を注入するには、独自の DIC ファクトリを作成するだけです。

$container = $app->getContainer();
$container['\Controllers\PeopleController'] = function ($c) {
    $peopleService = $c->get('\Services\PeopleService');
    return new Controllers\PeopleController($c, $peopleService);
};

もちろん、PeopleService 用の DIC ファクトリが必要になります。

$container['\Services\PeopleService'] = function ($c) {
    $peopleModel = new Models\PeopleModel;
    $addressModel = new Models\AddressModel;
    $autoModel = new Models\AutoModel;
    return new Services\PeopleService($peopleModel, $addressModel, $autoModel);
};

(PeopleModel、AddressModel、または AutoModel に依存関係がある場合は、それらの DIC ファクトリも作成します。)

于 2016-04-26T06:34:56.700 に答える