I'm new to modern method of dependency injection and I'm trying to figure out how to have a method pick which class to use based on a condition. I bet I've got my design structure off but I'm also not seeing how to do this in Aura DI through the config.
This is my Aura Config
<?php
namespace Aura\Cli_Project\_Config;
use Aura\Di\Config;
use Aura\Di\Container;
class Common extends Config {
public function define(Container $di) {
// utilities
$di->set(
'App\Inventory\Utilities\EmailParser',
$di->newInstance('App\Inventory\Utilities\PlancakeParser')
);
// commands
$di->params['App\Inventory\Command\IncomingOrder'] = array(
'stdio' => $di->lazyGet('aura/cli-kernel:stdio'),
'parser' => $di->get('App\Inventory\Utilities\EmailParser')
);
}
// ...
}
And this is the class in question that needs to use different classes depending on the "source" it finds.
<?php
namespace App\Inventory\Command;
use Aura\Cli\Stdio;
use App\Inventory\Utilities\EmailParser;
use App\Inventory\Sources\Etsy;
use App\Inventory\Sources\Amazon;
use App\Inventory\Sources\Ebay;
class IncomingOrder {
public function __construct(
Stdio $stdio,
EmailParser $parser) {
$this->stdio = $stdio;
$this->parser = $parser;
}
public function process() {
// other code to parse message
// source is set by determining where it came from
$source = 'Etsy';
switch($source) {
case 'Etsy' :
// This bit seems really wrong
$sourceParser = new Etsy\OrderParser();
break;
case 'Amazon' :
$sourceParser = new Amazon\OrderParser();
break;
case 'Ebay' :
$sourceParser = new Ebay\OrderParser();
break;
default :
$sourceParser = null;
}
// Do source specific processing
}
}
Is it that I need to split my processing at the point right after the source is determined so a new class can be initialized with that source as a parameter?
The only way I can see to do this in the config is to do a lazy anonymous function to return the proper source class but this also feels against modern design principles.
Something I would like to clarify is you don't need to use
setmethod like many of the di containers out here. You can modify the code toYou can make use of
setwhen you want to pass the same object to many other objects. Don't usenewInstancefor it will create the object on calling the same. You probably may need to make use oflazyNeworlazyGetfunctionalities.Regarding your question about dynamic decision making. Here is my thoughts, I did have came across this question some time before. But didn't see what I did so iirc what I did was injected a factory to
IncomingOrderclass which can create object. The good thing about it is if your source parse needs some sort of dependency you can make use of di inside the factory.Eg :
Hope that helps.
Thank you