I wanted to work with Interfaces and Dependency Injections in my YII 1.14 project. Here is the code that I have:
The interface:
interface IUserInterface
{
public function DoSomething();
}
The class:
class UserService implements IUserInterface
{
public function DoSomething()
{
echo "TEST TEST";
}
}
And my controller:
class AccountController extends Controller
{
protected $userService;
public function __construct(IUserInterface $userInterface)
{
$this->userService = $userInterface;
parent::__construct();
}
public function actionTest()
{
$this->userService->DoSomething();
}
}
But when I run my controller action, I get the following error: Argument 1 passed to AccountController::__construct() must be an instance of UserService, string given, called in …\framework\web\CWebApplication.php on line 359 and defined
The interface and the class are in a “services” folder and I’ve added that folder in the autoload in the config main file:
public void __construct(string $id, CWebModule $module=NULL)
A controller will be created automatically by Yii and the first param will be the id, not your userservice. And the id is a string (not your interface), that causes the error.
You can’t change the constructor as you like.
You have to assign the userservice as an extra method, called somewhere in your controller (actionXY …?).
OK, but then how do I use Dependency Injection? I implemented that code based on my experience with .Net MVC (using dependency injector tool) and I thought that it will work more or less the same. How can I inject the interface in the constructor of the controller and then use its methods?
OK, forget dependency injection. I want to use interface in my controller and call the interface methods in it, like I explained in my first post. I will have two or more classes that implement that interface, so using multiple classes as components, does not help my issue.
How and when are you deciding which of the concrete classes to use? What are the factors that determine which class is appropriate for the current request?
The whole point of using interfaces is that when you use in your controller a method that is declared in the interface, you don’t care (at the moment) about the class that implements it.
I don’t have to specify any class, that is the point of using an interface. I want to pass the interface in the controller, so I can use the methods that are defined in that interface (the body of those function will be in various classes that implement that interface).
I’m going to stop responding after this post because we’re going around in circles, but I’ll attempt to reiterate one more time…
At some point in your code, you’ll need to specify which of your concrete classes will be used to provide the functionality behind your interface methods. I was trying to determine when and how this decision is made so I could suggest a suitable place in Yii to provide access to the class.
That aside, if you’re looking for a framework comparable to .Net MVC, you might want to check out one of the more enterprise targeted frameworks, such as Symphony or Zend. These have features like dependency injection built in.