ehyiah/mapping-bundle

Symfony Bundle,轻松将对象映射到彼此

安装次数: 1,333

依赖关系: 0

建议者: 0

安全: 0

星标: 2

关注者: 1

分支: 2

公开问题: 0

类型:symfony-bundle

0.4.2 2024-06-23 17:57 UTC

README

Symfony bundle,可以轻松将一个对象映射到另一个对象。

它主要是为了在编辑时避免将完整的实体传递给symfony表单而构建的。但您可以用多种方式使用它。

它被设计得尽可能简单,所有映射都位于一个单独的对象中,该对象“知道”目标类和属性目的地。主要对象外没有配置。

主要服务有两个方法

  • mapToTarget:此方法将映射的Aware对象映射到目标对象。目标对象可以是另一个简单对象或实体。例如:您有一个表单,其data_class是一个对象,将代表实体的某些属性,例如用户。

  • mapFromTarget:此方法将执行相反的操作。它将对象(或标记为目标对象的实体)中的属性映射到映射的Aware对象中。

安装

确保Composer已全局安装,如Composer文档中的安装章节所述。

使用Symfony Flex的应用程序

打开命令行,进入您的项目目录,执行以下命令

$ composer require ehyiah/mapping-bundle

不使用Symfony Flex的应用程序

步骤1:下载Bundle

打开命令行,进入您的项目目录,执行以下命令以下载此Bundle的最新稳定版本

$ composer require ehyiah/mapping-bundle

步骤2:启用Bundle

然后,通过将其添加到项目config/bundles.php文件中注册的Bundle列表中来启用Bundle。

// config/bundles.php

return [
    // ...
    <vendor>\<bundle-name>\<bundle-long-name>::class => ['all' => true],
];

使用方法

为了使用此Bundle,您需要标记一个对象(基本上是一个DTO)具有Ehyiah\MappingBundle\Attributes\MappingAware属性

在同一个类中,只需标记您要映射到目标对象的所有属性即可使用相同的属性。如果目标类和映射的DTO中的属性具有相同的名称,则无需执行其他操作(请参阅下面的$text属性示例)。如果属性具有不同的名称,您可以使用target选项指定目标类中的名称。

由于映射逻辑使用propertyAccess组件,您可以在目标类中指定嵌套属性。请参阅以下示例中的zipcodestreet属性。

简单使用

1 - 创建一个将“保留”映射逻辑的DTO

    // src/DTO/MyAwesomeDTO

    use App\src\Entity;
    use Ehyiah\MappingBundle\Attributes;
    
    #[MappingAware(target: MyAwesomeEntity::class)]
    class MyAwesomeDTO
    {
        #[MappingAware]
        public string $text

        #[MappingAware(target: 'aBooleanProperty')]
        public bool $active
        
        #[MappingAware(target: 'address.zipcode')]
        public bool $zipcode
        
        #[MappingAware(target: 'address.street')]
        public bool $street
    }

2 - 在您的代码中注入MappingServiceInterface,并调用方法。

    use App\src\Entity\MyAwesomeEntity;
    use App\src\DTO\MyAwesomeDTO;
    use Ehyiah\MappingBundle\Attributes;
    use Ehyiah\MappingBundle\MappingServiceInterface;
    
    class SomeUsefulServiceOrHandlerOrController
    {
        public function __construct(
            private MappingServiceInterface $mappingService,
        ) {
        }

        public function handle()
        {
            $entity = new MyAwesomeEntity();
            $dto = new MyAwesomeDTO();
            
            $this->mappingService->mapToTarget($dto, $entity);
            $this->mappingService->mapFromTarget($entity, $dto);
        }
    }

如果您在控制器、处理器或其他需要的地方调用带有MappingServiceInterface标签的服务的mapToTarget()函数,该服务将获取带有MappingAware属性的属性,并将DTO中存储的值放入实体的属性中并刷新它们(默认值)。

高级使用

替换内置服务

存在一个默认服务,实现了MappingServiceInterface。但您可能需要创建一个实现MappingServiceInterface的服务来替换默认的内置服务。

创建您自己的服务

要创建自己的服务

  • 只需创建一个实现了MappingServiceInterface的服务,就无需做其他任何事情,无需注册或覆盖默认内置服务。编译器会为你完成所有工作。
  • 在这个服务中,你需要自己处理逻辑。
  • 当然,你也可以从默认服务的基本方法中获取灵感,并在你自定义的服务中进行修改。

转换器

有时你需要修改对象之间的数据。

示例:在你的源对象(SourceObject)中有一个字符串,需要在目标对象(TargetObject)中有一个日期时间。或者反过来

通过转换器(Transformers)可以轻松实现这一点。你可以轻松创建它们或使用一些预构建的。要创建它们,只需创建一个类并实现TransformerInterface

转换器将有两个方法:transformreverseTransform,你可以传递一个数组选项,这两个方法都将使用这些选项。

transform方法用于mapToTarget

reverseTransform方法用于mapFromTarget

在每个方法中,你都可以访问源对象(SourceObject)和目标对象(TargetObject)。

    // src/DTO/MySourceObject

    use Ehyiah\MappingBundle\Attributes;
    
    #[MappingAware(target: MyTargetObject::class)]
    class MySourceObject
    {
        #[MappingAware(transformer: \Ehyiah\MappingBundle\Transformer\DateTimeTransformer::class, options: ['option1' => 'value1'])]
        public string $date
    }
    // src/DTO/MyTargetObject

    class MyTargetObject
    {
        public DateTime $date
    }

转换器的高级使用

转换器可以是“开放的”或“狭窄的”。为了更好地理解,有一个易于理解的内置示例,即StringToDateTimeTransformerDateTimeTransformer

选择哪一个完全取决于你!它们之间的唯一区别在于你如何编写transform和reverseTransform方法。

狭窄的转换器

StringToDateTimeTransformer为例:它被称为狭窄的转换器,因为它只会接受将字符串转换为日期时间,以及将日期时间反转转换为字符串。它将从源对象中选取一个字符串并转换成目标对象中的日期时间对象(通过mapToTarget方法)。并将目标对象中的日期时间对象反转转换回源对象(通过mapFromTarget方法)

如果你尝试做相反的操作,将会抛出异常。

开放的转换器

DateTimeTransformer为例:它被称为开放的转换器,因为它不仅接受将字符串转换为日期时间和将日期时间反转转换为字符串

  • 还将接受将日期时间转换为字符串,以及将字符串反转转换回日期时间。
  • 但是,这取决于你如何编写transform和reverseTransform方法。

内置转换器列表

开放的

狭窄的

映射对象内的映射集合

如果你需要在初始映射类中拥有子映射元素,CollectionTransformer是完美的选择。

  • 它可以允许你将集合元素映射到另一个类(或者也可以映射到同一个类,以利用其他CollectionTransformer功能)
  • 它可以模拟clearMissing功能,以避免在未提交的元素上执行默认映射清除
  • 它可以进行深度链接