But there's something bugging me: What if we need services in these commands? Since we instanciate them in the (symfony) command, we can't use the usual autowiring. So do we have to autowire these services in the symfony command (not really a fan of this, because it means I must load all services of the commands inside my symfony command... not very clean imho), or is there anotherway to achieve it?
You could totally have your actions be services, then inject as a container into the console command class. The AutowireLocator attribute would make this a cinch. As a bonus, these services would be lazy, they wouldn't be instantiated until actually used.
You would need to change ActionCommandInterface::execute() to accept all the required arguments (instead of injecting these in the constructor). Then to get the correct action, instead of the match, you'd do something like the following:
Besides what @kbond suggests (which is a nice way to deal with it) you could implement a "CommandFactory" and delegate all the instantiation logic, it is a good option if you don't want to inject the whole commands collection into your service. You would use the factory like this
class CommandFactory
{
public function createAttackCommand(Character $player, Character $ai, FightResultSet $fightResultSet)
{
return new AttackCommand(
$this->serviceOne,
$this->serviceTwo,
$player,
$ai,
$fightResultSet
);
}
}
$playerAction = $this->commandFactory->createAttackCommand($player, $ai, $fightResultSet);
This is just a quick example, you can modify/improve any part of it. By the way, we'll talk about the Factory pattern in this tutorial :)
Cheers!
Please, log in to vote for this comment
|
Share Comment
"Houston: no signs of life" Start the conversation!
3 Comments
Looks really great!
But there's something bugging me: What if we need services in these commands? Since we instanciate them in the (symfony) command, we can't use the usual autowiring. So do we have to autowire these services in the symfony command (not really a fan of this, because it means I must load all services of the commands inside my symfony command... not very clean imho), or is there anotherway to achieve it?
Hey @Jeff_Merlu, great question!
You could totally have your actions be services, then inject as a container into the console command class. The AutowireLocator attribute would make this a cinch. As a bonus, these services would be lazy, they wouldn't be instantiated until actually used.
You would need to change
ActionCommandInterface::execute()to accept all the required arguments (instead of injecting these in the constructor). Then to get the correct action, instead of thematch, you'd do something like the following:Then, execute the action with:
Hope that helps!
Besides what @kbond suggests (which is a nice way to deal with it) you could implement a "CommandFactory" and delegate all the instantiation logic, it is a good option if you don't want to inject the whole commands collection into your service. You would use the factory like this
This is just a quick example, you can modify/improve any part of it. By the way, we'll talk about the Factory pattern in this tutorial :)
Cheers!
"Houston: no signs of life"
Start the conversation!