2

我试图理解依赖注入,理论上我明白了,但是,我想举一个例子来帮助我。但是,我收到以下错误

PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function Main\Services\UserService::__construct(), 0 passed
in ...

这是我的“主”文件,我称之为index.php

<?php 
#index.php
require_once 'vendor/autoload.php';

use Main\Controllers\UserController;
use Main\Services\UserService;
use Main\Models\UserModel;
use Pimple\Container;

$container = new Container;
$container['UserModel'] = function($c) {
    return new UserModel();
};

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

$container['UserController'] = function ($c) {
    echo "creating a new UserController\n";

    $aUserService = $c['UserService'];
    return new UserController($aUserService);
};

$myUserService = new $container['UserService'];
$myResult = $myUserService->parseGet();
echo $myResult, PHP_EOL;

这是传递给服务的模型

<?php
# Models/UserModel.php
namespace Main\Models;

class UserModel
{
    private $record;

    public function getRecord()
    {
        return [
            'first_name' => 'Bob',
            'last_name'  => 'Jones',
            'email'      => 'bj@example.com',
            'date_joined' => '11-12-2014',
        ];
    }
}

而且,这是服务,它将模型作为其构造函数参数

<?php
namespace Main\Services;

use Main\Models\UserModel;

class UserService
{
    private $userModel;

    public function __construct(UserModel $userModel)
    {
        echo "verifying that the userModel passed in was a valid UserModel\n";
        $this->userModel = $userModel;

         print_r($this->userModel->getRecord());
    }

    public function parseGet()
    {
        $retVal = $this->userModel->getRecord();

        return json_encode($retVal);
    }
}

所以,理论上,Pimple 应该能够实例化一个UserService对象。我什至验证了传递给UserService类的UserModel是一个有效的UserModel对象(很明显它打印出一个数组)

我错过了什么?有什么我没有解释的吗?

哦,这是 composer.json 文件

{
    "require": {
        "pimple/pimple": "~3.0"
    },
    "autoload": {
        "psr-4": {
            "Main\\" : "./"
        }
    }
}

我创建了一个 gitHub 链接,因此可以签出并运行该项目,而无需复制所有内容(https://github.com/gitKearney/pimple-example

解决方案

问题是我有一个额外的产品

$myUserService = new $container['UserService'];

太明显了,我看不出来

4

2 回答 2

1

$container['UserService']已经一个 UserService 对象。检查您的服务定义:

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

那就是它$container['UserService']return new UserService($c['UserModel'])调用的时候,对吧?

您的代码基本上是:

$o1 = new UserService($c['UserModel']);
$o2 = new $o2;
于 2017-08-30T23:00:22.000 回答
0

您可以使用依赖注入容器将自己从操作对象依赖的痛苦中解脱出来。UserService没有必要创建一个新的(如果它真的是一个服务)。在这种情况下,您可以$container一次性定义它,并在需要时使用它。

因此,您可以执行以下操作,而不是创建一个新UserService对象并调用其方法parseGet()(您在代码中所做的):

$myResult = $container['UserService']->parseGet();

当您定义以下内容时:

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

一旦您尝试访问 $container['UserService'],您将告诉 Pimple 如何处理 UserService 的创建

这就是为什么将依赖项定义为函数的原因。

这可能与您的问题有关为什么使用闭包进行分配而不是直接将值分配给键?

于 2017-08-31T17:03:50.837 回答