[英]Is this the right way to use dependency injection with the Service Container?
[英]Which is the correct way to use dependency container?
我正在使用Slim和php-di作為容器,我一直試圖弄清楚如何自動裝配依賴項但沒有成功。
我有App\\Models\\Planner.php
,我想將它注入App\\Controllers\\MealPlanner.php
,以及由不同端點/方法/操作調用的各種其他類和模型。
現在在Services.php 上,我正在創建 4 個服務 2 ,它們將傳遞給其他類,以及 2 個工廠,它們是Planner.php和MealPlanner.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
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();
}
}
<?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.