runopencode/traitor-bundle

通过基于定义的服务类使用的特性,通过方法注入将它们注入到服务中。

安装: 50

依赖: 0

建议者: 0

安全: 0

星标: 4

关注者: 4

分支: 0

开放问题: 0

类型:symfony-bundle

2.0.0 2017-04-26 09:23 UTC

This package is auto-updated.

Last update: 2024-09-17 10:10:32 UTC


README

Packagist Scrutinizer Code Quality Build Status Code Coverage Build Status

SensioLabsInsight

这是一个定义基于在服务类中使用的特性的额外服务/参数/值设置器注入的Symfony服务容器编译器传递。

在开始使用此包之前,请阅读以下文章(如果您还没有的话):[https://symfony.ac.cn/doc/current/components/dependency_injection/types.html](https://symfony.ac.cn/doc/current/components/dependency_injection/types.html),完全理解注入类型至关重要,因为此包推崇设置器注入(与构造器注入相比,它被视为非首选方法)以提高生产效率。

我们希望您仔细阅读此“readme”文件,并在使用之前理解此包的功能,以及它的所有优点和缺点,尤其是如果您不是计算机科学专业且有经验的开发者。

此包是如何工作的?

一句话总结:如果您的类在服务容器中注册为服务,并且该类使用了像\Psr\Log\LoggerAwareTrait这样的特性,此包将重新定义您的服务,在其定义中添加一个方法调用,注入适当的服务,例如,一个logger

因此,您不必为您的服务定义设置器注入,只需使用某种提供或用户定义的*AwareTrait,此包将提供适当的注入(当然,如果配置正确的话)。

您为什么要考虑定义设置器注入的这种方法?

假设您已经在服务容器中定义了服务,这些服务需要额外的注入,例如,在您的代码中将使用的服务。

例如

class MyService 
{
    public function __construct() {  }
}

您的 services.yml

services:
    my_service
        class: MyService

为了将logger服务注入到您的服务中,您必须修改您的类,例如,使用构造器注入。

class MyService 
{
    protected $logger

    public function __construct(\Psr\Log\LoggerInterface $logger) 
    {
        $this->logger = $logger;
    }
}        

您还必须修改 services.yml

services:
    my_service
        class: MyService
        argumets: [ '@logger' ]

在上面的例子中,实施了良好的服务注入实践。然而,有时这种良好的实践无法在合理的时间和精力内得到满足。

特剌托包拯救了这种情况

不如说,像上面例子那样做,而是使用一些特剌托和某种“魔法”来完成剩余的工作?我们前面的例子可以这样简单完成:

class MyService 
{
    use \Psr\Log\LoggerAwareTrait;

    public function __construct() {  }
}

这已经足够好了——您只需使用适当的特剌托,此包内的编译器传递将为您提供适当的服务类设置器注入。

开发此包的动机

开发此类包的动机的最好例子是GeneratorBundle:[https://github.com/symfony2admingenerator/GeneratorBundle](https://github.com/symfony2admingenerator/GeneratorBundle)。

特别是,GeneratorBundle为您生成了所有CRUD部分,包括表单类型,这些类型(按照此库作者的荣幸)已正确注册到服务容器中,并带有标签form.type。虽然这很好,但有时注入额外所需的服务可能会成为一个问题,这种情况相当常见。

为了进行此类注入,您需要确定您的表单类型已注册的服务名称,并通过配置文件修改该服务,例如通过在app/config/services.yml中覆盖其定义(利用配置级联)或通过编译器通过。

然而,当我们在一个有50种表单类型需要注入额外服务的项目上工作时,我们发现这些方法都花费了太多的时间。

因此,我们需要一个更优雅、更省力的解决方案。

还有其他类似的解决方案,比如JMSDiExtraBundle,它允许您通过注解实现相同的功能。

为什么这个包应该谨慎使用呢?

  • 仅应使用setter注入进行可选注入。然而,此解决方案还通过setter注入提出了所需服务的注入。这并不像Laravel的Facade那样糟糕,但如果在不了解注入类型的情况下使用,它可能会很危险,特别是对于不了解这种实践区别的开发者。
  • Symfony提出了一些定义服务的约定,以提高项目的生产力和可维护性。此包打破了这些约定,如果开发人员不熟悉此包的用法,他们可能会难以理解某些服务是如何获得其所需依赖的。
  • 第一次运行时的编译器通过可能会影响性能,因为此包分析了所有服务和它们所属类的所有特性,以及类的继承映射以及特性的相关使用。然而,通过配置,您可以缩小搜索范围并提高编译器通过的性能。

考虑到上述所有危险,此包可以在某些用例中帮助您很多,以牺牲良好的编码实践为代价,提供灵活性和生产力,您应该在出现这种情况时使用此包。

请注意,出于明显的原因,此包不应用于可重新分发的Symfony包

配置

通过composer安装此包,composer require runopencode/traitor-bundle,并在您的AppKernel.php中注册它

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = [
        
            ...
            
            new RunOpenCode\Bundle\Traitor\TraitorBundle()
            
            ...
            
        ];
        return $bundles;
    }

}

并对其进行配置,下面的示例提供了完整的配置示例

runopencode_traitor:
    use_common_traits: false             
    inject:
        'Full\Qualified\Trait\Namespace':
            - [ 'setterMethodName', [ '@service_name', 'or_parameter_value' ]]
            - { method: 'otherSetterMethodName', arguments: [ '@service_name', 'or_parameter_value' ] }
    filters:
        tags: [ 'form.type', 'other_tag' ]
        namespaces: [ '\Namespace\Prefix1', 'Namespace\Prefix2' ]
    exclude:
        tags: [ 'tag.to.exclude' ]
        services: [ 'my.service.to_exclude' ]
        classes: [ '\Exclude\Services\ThatUsesThisClass', '\Or\Uses\ThisClass' ]
        namespaces: [ '\Exclude\AllServices\WithClasses\WithinThisNamespace\' ]
  • use_common_traits:可选。此包在\RunOpenCode\Bundle\Traitor\Traits命名空间内提供了一些常用的特性,以提高您的生产力。如果您正在使用它们,将此参数设置为true,它将添加这些特性到注入映射。下面给出了您可以“开箱即用”使用的特性的完整列表。
  • inject:可选。一个关联数组,包含应进行检查的特性和它们的使用,如果它们在服务类中使用,则特性映射定义setter注入的方式与Symfony的calls定义一样,是一个数组,第一个参数定义要调用的方法,第二个参数是一个数组,包含传递给该方法调用的参数,或者,您可以使用具有键methodattributes的关联数组。
  • filters:可选。为了不扫描所有服务类,您可以缩小子集以包含特定的命名空间和/或服务标记。确定哪个类使用哪个特性可能是昂贵的,此包检查继承以及相关特性的使用(例如,如果特性使用特性)。
  • exclude:可选。您可以排除某些服务、标记服务、服务类和命名空间,以便它们甚至可以考虑进行此类注入。

XML配置

当然,您可以通过XML配置(推荐方式)来配置包,这样您将可以使用XML模式文件进行验证和智能感知,以便配置您的配置文件。

提供的常见特性

如前所述,此包为您提供了一些常见特性,您可能使用也可能不使用它们。但是,如果您使用它们,请确保在配置中设置use_common_traits为true,并且inject映射将附加以下定义。

'Symfony\Component\DependencyInjection\ContainerAwareTrait': ['setContainer', ['@service_container']]
'Psr\Log\LoggerAwareTrait': ['setLogger', ['@logger']]
'RunOpenCode\Bundle\Traitor\Traits\DoctrineAwareTrait': ['setDoctrine', ['@doctrine']]
'RunOpenCode\Bundle\Traitor\Traits\EventDispatcherAwareTrait': ['setEventDispatcher', ['@event_dispatcher']]
'RunOpenCode\Bundle\Traitor\Traits\FilesystemAwareTrait': ['setFilesystem', ['@filesystem']]
'RunOpenCode\Bundle\Traitor\Traits\KernelAwareTrait': ['setKernel', ['@kernel']]
'RunOpenCode\Bundle\Traitor\Traits\MailerAwareInterface': ['setMailer', ['@mailer']]
'RunOpenCode\Bundle\Traitor\Traits\PropertyAccessorAwareTrait': ['setPropertyAccessor', ['@property_accessor']]
'RunOpenCode\Bundle\Traitor\Traits\RequestStackAwareTrait': ['setRequestStack', ['@request_stack']]
'RunOpenCode\Bundle\Traitor\Traits\RouterAwareTrait': ['setRouter', ['@router']]
'RunOpenCode\Bundle\Traitor\Traits\AuthorizationCheckerAwareTrait': ['setAuthorizationChecker', ['@security.authorization_checker']]
'RunOpenCode\Bundle\Traitor\Traits\SessionAwareTrait': ['setSession', ['@session']]
'RunOpenCode\Bundle\Traitor\Traits\TwigAwareTrait': ['setTwig', ['@twig']]
'RunOpenCode\Bundle\Traitor\Traits\TranslatorAwareTrait': ['setTranslator', ['@translator']]
'RunOpenCode\Bundle\Traitor\Traits\ValidatorAwareTrait': ['setValidator', ['@validator']]
'RunOpenCode\Bundle\Traitor\Traits\TokenStorageAwareTrait': ['setTokenStorage', ['@security.token_storage']]

通常,常见特性可以帮助您在注入以下服务时提高生产效率:

  • service_container
  • logger
  • doctrine
  • event_dispatcher
  • filesystem
  • kernel
  • mailer
  • property_accessor
  • request_stack
  • router
  • security.authorization_checker
  • session
  • twig
  • translator
  • validator
  • security.token_storage