簡體   English   中英

哪個是使用依賴容器的正確方法?

[英]Which is the correct way to use dependency container?

我正在使用Slimphp-di作為容器,我一直試圖弄清楚如何自動裝配依賴項但沒有成功。

我有App\\Models\\Planner.php ,我想將它注入App\\Controllers\\MealPlanner.php ,以及由不同端點/方法/操作調用的各種其他類和模型。

現在在Services.php 上,我正在創建 4 個服務 2 ,它們將傳遞給其他類,以及 2 個工廠,它們是Planner.phpMealPlanner.php ,它們在index.php的路由器中調用。

現在 MealPlanner 被定義為一個服務,它可以被直接調用,即從$app->any('/mealplanner/{action}', \\MealPlanner::class); ,如果我刪除$app->set('MealPlanner', ...)我會得到“Callable MealPlanner 不存在”,為什么它可以在不訪問容器的情況下調用?

其次,假設我想將 Fruits 類與 Planner.php 一起注入 MealPlanner,為此我必須添加一個新服務$container->set("Fruits", (){ return App\\Models\\Fruits.php(PDO $db, $UserId) })然后在 MealPlanner 服務上我必須在那里傳遞水果容器,然后在 MealPlanner 控制器上它現在是:

public function __construct(App\Models\Planner $planner, App\Models\Fruits $fruits)

就個人而言,必須通過服務容器傳遞它們,然后必須在控制器上更改它們,這很煩人,我可能在這里誤解了一些東西..

假設我決定放棄上面的代碼,取而代之的是“slim 將實例化容器” ,MealPlanner.php 現在將是

namespace App\Controllers;
use Psr\Container\ContainerInterface;

class MealPlanner extends InvokeAction {

  public function __construct(ContainerInterface $container){
    $this->container = $container;
  }

  public function init($request, $response, $args){
    // return something
  }    
}

我必須從容器中刪除 MealPlanner 工廠,因此路由類定義將停止工作,我必須使用它的絕對路徑才能工作$app->any('/mealplanner/{action}', \\App\\Controllers\\Planner::class); ,現在所有的服務,比如“數據庫”和“規划師”都可以通過容器訪問,但我仍然需要創建服務,比如 Fruits,所以不了解自動裝配是如何工作的,因為它們沒有定義絕對路徑類型提示時。

我創建了一個結合 Slim 4 和 Eloquent ORM 的框架,稱為Willow 以下是我如何使用 PHP-DI:

應用程序.php

<?php
declare(strict_types=1);
namespace Willow\Main;
use DI\ContainerBuilder;
use Slim\Factory\AppFactory;
class App
{
    public function __construct()
    {
        // Set up Dependency Injection
        $builder = new ContainerBuilder();

        // Read in each config file to inject. See db.php below as an example
        foreach (glob(__DIR__ . '/../../config/*.php') as $definitions) {
            $builder->addDefinitions(realpath($definitions));
        }
        $container = $builder->build();

        // Get an instance of Slim\App and inject the container.
        AppFactory::setContainer($container);
        $app = AppFactory::create();
    }
}

配置/db.php

<?php
declare(strict_types=1);
use Illuminate\Database\Capsule\Manager as Capsule;
use Psr\Container\ContainerInterface;
// By returning this array it sets up Capsule::class to be injected via DI
return [
    Capsule::class => function (ContainerInterface $c) {
        $eloquent = new Capsule;
        $eloquent->addConnection([
            'driver'    => env('DB_DRIVER') ?? 'mysql',
            'host'      => getenv('DB_HOST'),
            'port'      => getenv('DB_PORT') ?? '',
            'database'  => getenv('DB_NAME'),
            'username'  => getenv('DB_USER'),
            'password'  => getenv('DB_PASSWORD'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => ''
        ]);
        // Make this Capsule instance available globally via static methods
        $eloquent->setAsGlobal();
        // Setup the Eloquent ORM...
        $eloquent->bootEloquent();
        // Set the fetch mode to return associative arrays.
        $eloquent->setFetchMode(PDO::FETCH_ASSOC);
        return $eloquent;
    }
];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM