dunglas/action-bundle

此软件包已被废弃,不再维护。作者建议使用 symfony/dependency-injection 软件包。

重新设计 Symfony 控制器

安装次数: 403,545

依赖项: 5

建议者: 0

安全: 0

星标: 264

关注者: 14

分支: 15

开放问题: 7

类型:symfony-bundle

v0.4.1 2017-05-12 12:56 UTC

This package is auto-updated.

Last update: 2022-02-01 12:55:01 UTC


README

Build Status Build status SensioLabsInsight Scrutinizer Code Quality StyleCI

此软件包是 Symfony 框架控制器系统 和其 命令系统 的替代品。

它使用方便,但不会受到原始系统的缺点的影响

  • 操作和控制台类由软件包自动 注册为服务
  • 它们的依赖关系在构造函数中 显式注入(不再需要访问服务容器的丑陋方式)使用 依赖注入组件的自动装配功能
  • 由于 __invoke() 方法,每个类只有一个操作(但如果你愿意,你仍然可以创建具有多个操作的类)
  • 100% 兼容常见的库和软件包,包括 SensioFrameworkExtraBundle 注释

DunglasActionBundle 允许创建可重用、框架无关(尤其是在使用 PSR-7 桥接器 时)和易于单元测试的类。

有关此软件包背后的历史,请参阅 https://github.com/symfony/symfony/pull/16863#issuecomment-162221353

关于 Symfony >=3.3 用户的通知

如果您使用的是 3.3 或更高版本的 Symfony,则不需要使用此软件包,因为所有功能都已移植到 Symfony 中。您可以在 Symfony 博客 或在 Symfony 文档 中了解更多信息。

安装

使用 Composer 安装此软件包

composer require dunglas/action-bundle

将软件包添加到您的应用程序内核中

// app/AppKernel.php

public function registerBundles()
{
    return [
        // ...
        new Dunglas\ActionBundle\DunglasActionBundle(),
        // ...
    ];
}

可选:要使用 @Route 注释,请将以下行添加到 app/config/routing.yml

app:
    resource: '@AppBundle/Action/' # Use @AppBundle/Controller/ if you prefer
    type:     'annotation'

如果您不想使用注释但更喜欢原始 YAML,请使用以下语法

foo:
    path:      /foo/{bar}
    defaults:  { _controller: 'AppBundle\Action\Homepage' } # this is the name of the autoregistered service corresponding to this action

使用方法

  1. 在您的软件包的 Action\ 命名空间中创建一个可调用的类
// src/AppBundle/Action/MyAction.php

namespace AppBundle\Action;

use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class Homepage
{
    private $router;
    private $twig;

    /**
     * The action is automatically registered as a service and dependencies are autowired.
     * Typehint any service you need, it will be automatically injected.
     */
    public function __construct(RouterInterface $router, \Twig_Environment $twig)
    {
        $this->router = $router;
        $this->twig = $twig;
    }

    /**
     * @Route("/myaction", name="my_action")
     *
     * Using annotations is not mandatory, XML and YAML configuration files can be used instead.
     * If you want to decouple your actions from the framework, don't use annotations.
     */
    public function __invoke(Request $request)
    {
        if (!$request->isMethod('GET')) {
            // Redirect to the current URL using the the GET method if it's not the current one
            return new RedirectResponse($this->router->generateUrl('my_action'), 301);
        }

        return new Response($this->twig->render('mytemplate.html.twig'));
    }
}

或者,您可以在软件包的 Controller 目录中创建一个典型的 Symfony 控制器类,其中包含多个 *Action 方法,它将以相同的方式自动装配。

没有第二步!您已经完成了。

您的项目软件包的 Action/Controller/ 目录中的所有类都自动注册为服务。按照惯例,服务名称是类的完全限定名称。

例如,示例中的类自动注册为 AppBundle\Action\Homepage

支持其他类/标记

类名 自动添加的标签 目录
命令 console.command 命令
EventSubscriberInterface kernel.event_subscriber EventSubscriber
Twig_ExtensionInterface twig.extension Twig

感谢依赖注入组件的自动装配特性,您只需要在构造函数中指定所需的依赖项,它们将自动初始化和注入。

可以通过显式定义一个遵循相同约定的服务名称来轻松自定义服务定义

# app/config/services.yml

services:
    # This is a custom service definition
    'AppBundle\Action\MyAction':
        arguments: [ '@router', '@twig' ]

    'AppBundle\Command\MyCommand':
        arguments: [ '@router', '@twig' ]
        tags:
            - { name: console.command }

    # With Symfony < 3.3
    'AppBundle\EventSubscriber\MySubscriber':
        class: 'AppBundle\EventSubscriber\MySubscriber'
        tags:
            - { name: kernel.event_subscriber }

此包还挂钩到路由组件(如果可用):当使用如示例中的@Route注解时,路由将自动注册:包会猜测与注解中指定的路径映射的服务。

深入TestBundle以发现更多示例,例如轻松使用自定义服务(无需任何配置)或包含多个操作的类。

使用Symfony微框架

您可能会对如何使用此包与Symfony "Micro" 框架一起使用感兴趣。

让我们开始吧

// MyMicroKernel.php

use AppBundle\Action\Homepage;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;

final class MyMicroKernel extends Kernel
{
    use MicroKernelTrait;

    public function registerBundles()
    {
        return [
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Dunglas\ActionBundle\DunglasActionBundle(),
            new AppBundle\AppBundle(),
        ];
    }

    protected function configureRoutes(RouteCollectionBuilder $routes)
    {
        // Specify explicitly the controller
        $routes->add('/', Homepage::class, 'my_route');
        // Alternatively, use @Route annotations
        // $routes->import('@AppBundle/Action/', '/', 'annotation');
    }

    protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
    {
        $c->loadFromExtension('framework', ['secret' => 'MySecretKey']);
    }
}

是不是很神奇?

想看一个更高级的例子? 查看我们的测试微内核

配置

# app/config/config.yml

dunglas_action:
    directories: # List of directories relative to the kernel root directory containing classes to auto-register.
        - '../src/*Bundle/{Controller,Action,Command,EventSubscriber}'
        # This one is not registered by default
        - '../src/*Bundle/My/Uncommon/Directory'
    tags:
        'Symfony\Component\Console\Command\Command': console.command
        'Symfony\Component\EventDispatcher\EventSubscriberInterface': kernel.event_subscriber
        'My\Custom\Interface\To\Auto\Tag':
            - 'my_custom.tag'
            - [ 'my_custom.tag_with_attributes', { attribute: 'value' } ]

致谢

此包由Kévin Dunglas优秀的贡献者提供。由Les-Tilleuls.coop赞助。