studioignis / cmd
将命令支持添加到您的应用程序中。灵感来源于laracasts/commander。
Requires
- php: >=5.5.0
- illuminate/support: >=4.1
Requires (Dev)
- illuminate/container: >=4.1
- phpspec/phpspec: ~2.1@dev
This package is not auto-updated.
Last update: 2024-09-14 15:47:38 UTC
README
StudioIgnis Cmd
轻松实现基于命令的架构。
灵感来源于laracasts/commander
安装
通过将包添加到您的composer.json文件中通过composer安装
{ "require": { "studioignis/cmd": "~1.0" } }
或者使用以下命令
$ composer require studioignis/cmd:~1.0
用法
非常简单,您只需要命令总线实例,然后就可以开始执行命令!您可以手动启动实例或使用包含的Laravel服务提供程序。
手动启动
您需要一个\StudioIgnis\Cmd\Support\Container
和\StudioIgnis\Cmd\NameInflector
的实现。
由于这取决于您的框架,您需要创建自己的容器实现。您可以查看包含的Laravel实现,了解如何实现它,它非常简单。
对于名称变换器,另一方面,您可以使用包含的\StudioIgnis\Cmd\DefaultNameInflector
,或者您可以创建自己的。
$container = new StudioIgnis\Cmd\CommandBus( new Acme\Foo\Container($whatever), new StudioIgnis\Cmd\DefaultNameInflector );
使用Laravel
如果您正在使用Laravel框架,您可以利用包含的服务提供程序。您需要将其添加到app/config/app.php
文件中的providers
数组中
'providers' => [ // ... 'StudioIgnis\Cmd\Laravel\ServiceProvider', ],
现在您可以通过依赖注入来获取命令总线,如下所示
use StudioIgnis\Cmd\Bus; class FooController { public function __construct(Bus $commandBus) { // ... } }
处理器
处理器可以像您需要的那样复杂,但它们只需要实现StudioIgnis\Cmd\Handler
接口。
此接口定义了一个方法,即handle(Command $command)
,如您所见,它接收相应的命令实例。
让我们看看一个(过分简化的)示例
namespace Acme\User\Handler; use StudioIgnis\Cmd\Command; use StudioIgnis\Cmd\Handler; use Acme\User\Command\SignUp as SignUpCommand; class SignUp implements Handler { public function handle(UserRepository $users) { $this->users = $users; } public function handle(Command $command) { /** @var SignUpCommand $command */ $this->users->add($command->name, $command->email, $command->password); } }
自动处理器解析
由于默认名称变换器会处理它,因此不需要为命令注册处理器,只要命名空间是可预测的。
变换器将命令类名中的所有"Command"替换为"Handler",例如,Acme\User\Command\CreateUser
将结果为处理器Acme\User\Handler\CreateUser
。
您不必遵循此命名空间约定,因为这只是一个单词替换,只需注意命令的处理器对应物最终会变成什么。
手动设置处理器
另一种,不太神奇但有时更受青睐的方法是手动为每个命令注册处理器
$bus->setHandler( 'Acme\User\Command\CreateUser', 'Acme\User\Command\CreateUserHandler' );
这样,您就不必预测处理器最终会出现在哪里,只需告诉总线在哪里找到它即可。
如上例所示,我们传递处理器全限定名(FQN)字符串。通过这样做,命令总线将使用容器解析处理器,从而实现懒加载。另一种实现懒加载处理器的方法是传递一个返回处理器实例的闭包。或者,您可以直接传递一个已经实例化的处理器。
命令
命令类是简单的DTO,但它们必须扩展抽象的StudioIgnis\Cmd\Command
。这个抽象基类让事情变得简单一些。
您的命令应定义一个数组,您可以自动获取这些属性,而无需定义getter。
此基命令类还确保命令可以转换为数组并序列化为JSON。
以下是一个示例
namespace Acme\User\Command; use StudioIgnis\cmd\Command; class SignUp extends Command { public function __construct($name, $email, $password) { $this->attributes = compact('name', 'email', 'password'); } }
现在您可以通过这种方式访问属性
// One by one $name = $signUpCommand->name; $email = $signUpCommand->email; $password = $signUpCommand->password; // As an array $signUpCommand->toArray(); // As a json string $json = $signUpCommand->toJson(); $json = (string) $signUpCommand; $json = json_encode($signUpCommand);
执行命令
一旦您有了准备好的命令总线实例并注册了处理器(或未注册),执行命令就非常简单。让我们使用上面定义的命令。
$command = new \Acme\User\Command\SignUp( 'JohnDoe', 'john.doe@example.com, 'password!' ); $bus->execute($command);
特性
有两个特性可以帮助使命令执行更简洁。一个是一般的,另一个是专门为Laravel设计的。
StudioIgnis\Cmd\CmdTrait
此特性添加了 cmd($commandName, array $input)
方法。它的目的是通过传递命令类名和用作命令参数的输入数组,使初始化命令更加简单。
$input = [ 'name' => $this->input->get('name'), 'email' => $this->input->get('email'), 'password' => $this->input->get('password'), ]; $this->cmd('Acme\User\Command\SignUp', $input);
StudioIgnis\Cmd\Laravel\CmdTrait
此特性使用前一个特性,因此您只需添加此特性。
它添加了三个新方法: execute($commandName, array $input = null)
、getInput(array $input = null)
和 getCommandBus()
。
思路相同,但它还通过调用另一个特质的 cmd()
方法来执行命令。
getInput(array $input = null)
如果没有提供 $input
,将返回 Laravel 的 Input::all()
。
getCommandBus()
将返回 App::make('StudioIgnis\Cmd\Bus')
。
如果不想使用“外观”调用,这两个方法都可以被覆盖。
许可协议
版权所有 (c) 2014 Luciano Longo
特此授予任何获得本软件及其相关文档副本(“软件”)的人免费使用软件的权利,不受任何限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许软件的接受者为此目的进行操作,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“现状”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和无侵权性保证。在任何情况下,作者或版权所有者不对任何索赔、损害或其他责任负责,无论这些责任是基于合同、侵权或其他原因,以及与软件或软件的使用或其他交易有关。