Hello. BotMan's commands act like Controllers in MVC. It would be nice if BotMan could support controller-as-a-service pattern with ability to inject dependencies into command constructor.
Benefits:
Examples:
We can use framework-agnostic interface for DI container:
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md
It is possible to implement this feature without BC break:
1) Add setContainer(ContainerInterface $container) method to BotMan class.
2) Retrieve a service from container only if container is set and not null. I suggest to modify this part: https://github.com/botman/botman/blob/master/src/BotMan.php#L634+L651
protected function getCallable($callback)
{
if ($callback instanceof Closure) {
return $callback;
}
if (is_array($callback)) {
return $callback;
}
if (strpos($callback, '@') === false) {
$callback = $this->makeInvokableAction($callback);
}
list($class, $method) = explode('@', $callback);
- return [new $class($this), $method];
+ $command = $this->container ? $this->container->get($class) : new $class($this);
+
+ return [$command, $method];
}
I can create PR with tests for this feature.
Hey,
yeah, a PR for this would be great.
This is a great addition to the library.
Just encountered this PSR-11 container-based functionality, awesome!
Is it correct that such an approach is not mentioned in the documentation?
$botman->setContainer($dependencyInjectionContainer);
$botman->hears('hello', \Project\BotMan\Callables\Hello::class);
namespace Project\BotMan\Callables;
use BotMan\BotMan\BotMan;
class Hello
{
public function __invoke(BotMan $bot): void
{
$bot->reply('Hello World');
}
};
@holtkamp Yes, this is not mentioned in the documentation. Autowiring only works for constructor arguments, for example:
class SendEmailCommand
{
public function __construct(EmailSender $emailSender)
{
$this->emailSender = $emailSender;
}
public function __invoke(BotMan $bot): void
{
$this->emailSender->send(...);
}
}
$botman->setContainer($dependencyInjectionContainer);
$botman->hears('send', \App\Command\SendEmailCommand::class);
Thanks! Works great in combination with http://php-di.org
@mpociot might be an idea to open a "low-priority" issue to add documentation for this? Maybe the examples above already suffice to get people on the right path 馃