I have a Chain of Command pattern implemented, with modules that implement an interface:
interface IRequestHandler
{
public function handle(&$offset, &$tripData, $request = null);
public function setSuccessor(OffsetRequestHandler $handler);
}
I set up a chain of modules that modify the $offset
and $tripData
objects if necessary (I guess that it is not exactly a chain of command pattern, but it gets the job done :)
I would like to start using dependency injection whenever it is possible to ease the process of writing unit tests. My question is: how to handle it, if each module may need different set of services? I can go with Auryn, and let it automatically instantiate all dependencies for each module (at least I hope that I can), but that shouldn't be necessary in theory...
Update:
To build the chain I take names of classes from the config file, I instantiate them, and I arrange them in a queue. The controller is not aware of the dependencies that each module needs. Right now, there are none, because each module creates needed objects by itself (and this is what I want to change). I don't want to inject each module with the container, because this will turn into a Service locator pattern.
Update 2:
The need:
I get a set of data from external resources, and I need to process it to get some metrics. However, the data may be corrupted, sent in batches, or whatever, and my script needs to fix it (as much as possible). The types of problems may depend on the external resource the data comes from. And the situation is dynamic, meaning that new types of problems, and new external resources may appear in the future.
My idea:
Create modules. Each module will address specific problem. Arrange the modules in a queue (as the order of the modules may be important), and execute them injecting the incoming data as a parameter.
The solution is heavily inspired by this article on SitePoint.
But instead of creating the instances one by one like in the example:
$firstHandler = new FirstHandler();
$secondHandler = new SecondHandler();
$thirdHandler = new ThirdHandler();
//the code below sets all successors through the first handler
$firstHandler->setSuccessor($secondHandler);
$secondHandler->setSuccessor($thirdHandler);
$result = $firstHandler->handle($request);
I pull the names of the classes from the config file, and I create them with a foreach
loop:
$modulesQueue = $config->get("extensions");
foreach ( $modulesQueue as $moduleName ) {
$moduleName = "extensions\\".$moduleName;
$startModule->setSuccessor(new $moduleName());
}
// Starting the chain:
$ret = $startModule->handle($offset, $tripDataObject, $requestData);
The problem:
If I create instance of the classes like that, I don't see what each module needs to have injected (at this moment nothing, as there is no DI applied - each module instantiate services it needs). So I see two options here: either I switch to manual creation of the modules (which is not flexible at all), or I start using Reflection
to find out what each module needs, and provide it.
MockRequestHandler
into your command objects in your unit tests. Just don't use the config file mechanism in your tests, what is the problem?