Reputation: 965
I'm having some issues with dependency injection that I'd like to clearify. The first thing to mention is a dependency injection container (DIC) I implemented, which is capable of registering and resolving dependencies through constructors using ReflectionClass.
$container = new DiC;
$container->register('session', 'CSession');
$container->register('response', 'CResponse');
$container->register('model', 'CSomeModel');
$container->register('view', 'CSomeView');
$container->register('controller', 'CSomeController');
A dependent controller:
class CSomeController extends CController
{
public function __construct(CSomeModel $model, CSomeView $view)
{
// assign arguments here
}
}
Now the controller can be instantiated through DIC:
$controller = $container->resolve('controller');
I like this approach because it is automated and descriptive, however class CController depends on specific classes CSomeModel, CSomeView which is bad. MVC triads should be instantiated independently - I cannot pass COtherView to CSomeController for example.
My second guess is to inject the DIC:
class CSomeController extends CController
{
public function __construct(DiC $dic)
{
// resolve dependencies through $dic
}
}
This one makes DiC object global, many people argue this is not the way to implement DI.
Is there a third way that eliminates the weaknesses from both approaches?
Upvotes: 3
Views: 410
Reputation: 150
If your looking for "auto-wiring", switch to Interfaces and implement your concrete Model/View/etc. classes against that interface. That way you could use reflection to pair up both sides.
It would also make sense to have a mechanism for explicitly specifying dependencies at the container level.
Upvotes: 1
Reputation:
I think both approaches are relevant. In case you want to be more flexible in the first approach you could change the constructor to have a parent class as a dependency. Then every object that inherits from that parent class could be injected. I.e.
class CSomeModel extends AbstractCModel {}
class CSomeOtherModel extends AbstractCModel {}
public function __construct(AbstractCModel $model, AbstractCView $view) {}
The second approach is suitable if you need to access factories. I.e. if you need to access multiple instances of the same object.
Upvotes: 1