I'm trying to understand dependency injection, and I in theory, I get it, but, I wanted to make an example just to help me. However, I'm getting the following error
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function Main\Services\UserService::__construct(), 0 passed
in ...
Here's my "main" file, I've called it 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;
Here's the model that's being passed into the service
<?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',
];
}
}
And, here's the service, which takes the model as it's constructor argument
<?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);
}
}
So, in theory, Pimple should be able to instantiate a UserService object. I even verified that the UserModel passed into the UserService class is a valid UserModel object (which it is as is evident that it prints out an array)
What am I missing? Is there something that I have failed to account for?
Oh, here's the composer.json file
{
"require": {
"pimple/pimple": "~3.0"
},
"autoload": {
"psr-4": {
"Main\\" : "./"
}
}
}
I made a gitHub link so the project can be checked out and ran without having to copy past everything (https://github.com/gitKearney/pimple-example)
The problem was I have an extra new in the line
$myUserService = new $container['UserService'];
It was so obvious, I couldn't see it
$container['UserService']
already is a UserService object. check yer service definition:
$container['UserService'] = function ($c) {
return new UserService($c['UserModel']);
};
That sets $container['UserService']
to be return new UserService($c['UserModel'])
when it's invoked, right?
Your code is basically going:
$o1 = new UserService($c['UserModel']);
$o2 = new $o2;