bluepsyduck/mapper-manager

用于将对象映射到其他对象的工具管理器。

1.3.0 2022-02-22 17:37 UTC

This package is auto-updated.

Last update: 2024-09-22 23:22:14 UTC


README

GitHub release (latest SemVer) GitHub build Codecov

正如其名所暗示的,Mapper Manager 是不同类型对象之间映射器的管理器。

映射器

映射器支持不同类型的映射器,这些映射器在评估它们是否可以映射特定的一对对象时有所不同。每种类型的映射器都附带一个接口和相应的适配器,以便管理器处理此类映射器。如果需要,客户端代码中可以始终添加新类型。

如果映射器需要访问 MapperManager 来映射其他对象,例如,您必须实现 MapperManagerAwareInterface 以将其注入到映射器实例中,以避免循环依赖。您可以使用 MapperManagerAwareTrait 通过简单的设置方法来实现此接口。

静态映射器

实现 StaticMapperInterface 的静态映射器仅根据类知道它支持源和目标对象的组合,而不了解对象的实际实例。该支持在映射器添加到管理器时评估一次。

注意:源和目标类的必须完全匹配,静态映射器不会检查任何继承。例如,如果有类 A 和类 B extends A,并且映射器返回 A 作为支持的类,如果传递 B 的实例,则不会匹配。如果必须支持继承,请改用动态映射器。

建议尽可能始终使用静态映射器,因为与动态映射器相比,使用静态映射器在管理器中匹配映射器更快。

示例

<?php

use BluePsyduck\MapperManager\Mapper\StaticMapperInterface;

class ExampleStaticMapper implements StaticMapperInterface
{
    /**
     * Returns the source class supported by this mapper.
     * @return string
     */
    public function getSupportedSourceClass(): string 
    {
        return DatabaseItem::class;
    }

    /**
     * Returns the destination class supported by this mapper.
     * @return string
     */
    public function getSupportedDestinationClass(): string
    {
        return ResponseItem::class;
    }
    
    /**
     * Maps the source object to the destination one.
     * @param DatabaseItem $source
     * @param ResponseItem $destination
     */
    public function map($source, $destination): void
    {
        $destination->setName($source->getName())
                    ->setDescription($source->getDescription());
    }
}

动态映射器

实现 DynamicMapperInterface 的动态映射器将在实际对象实例的基础上决定是否支持源和目标对象的组合。这允许根据涉及的两个对象添加额外的支持标准。对于传递给映射器管理器的每个源和目标对象,都会重新评估支持。

示例

<?php

use BluePsyduck\MapperManager\Mapper\DynamicMapperInterface;

class ExampleDynamicMapper implements DynamicMapperInterface
{
    /**
     * Returns whether the mapper supports the combination of source and destination object.
     * @param object $source
     * @param object $destination
     * @return bool
     */
    public function supports($source, $destination): bool
    {
        return $source instanceof DatabaseItem::class 
            && $destination instanceof ResponseItem::class
            && $source->getType() === 'public'; // Additional condition not possible with a static mapper.
    }
    
    /**
     * Maps the source object to the destination one.
     * @param DatabaseItem $source
     * @param ResponseItem $destination
     */
    public function map($source, $destination): void
    {
        $destination->setName($source->getName())
                    ->setDescription($source->getDescription());
    }
}

用法

映射器管理器的使用相当直接:创建 MapperManager 类的实例,添加一些适配器,然后添加您的实际映射器实现。

<?php

use BluePsyduck\MapperManager\MapperManager;
use BluePsyduck\MapperManager\Adapter\DynamicMapperAdapter;
use BluePsyduck\MapperManager\Adapter\StaticMapperAdapter;

$mapperManager = new MapperManager();

// Add the default adapters included in the library.
$mapperManager->addAdapter(new StaticMapperAdapter());
$mapperManager->addAdapter(new DynamicMapperAdapter());

// Add your actual mappers.
$mapperManager->addMapper(new ExampleStaticMapper());
$mapperManager->addMapper(new ExampleDynamicMapper());

// Actually map objects.
$mapperManager->map($databaseItem, $responseItem);

Mezzio

当使用 Mezzio 时,您可以将库的 ConfigProvider 添加到您的应用程序配置中,并通过容器使用 MapperManagerInterface::classMapperManager::class 作为别名来访问已初始化的映射器管理器。

将以下配置添加到您的项目中以自定义管理器

<?php

use BluePsyduck\MapperManager\Constant\ConfigKey;

[
    ConfigKey::MAIN => [
        ConfigKey::ADAPTERS => [
            // The aliases of the adapters to add to the manager.
            // The adapters must be accessible through the container with these aliases.
            // The StaticMapperAdapter and DynamicMapperAdapter are added automatically.
        ],
        ConfigKey::MAPPERS => [
            // The aliases of the mappers to add to the container.
            // The mappers must be accessible through the container with these aliases.
        ],
    ],
];

然后通过容器访问映射器管理器

<?php

use BluePsyduck\MapperManager\MapperManagerInterface;

// Fetch the mapper manager from the container.
$mapperManager = $container->get(MapperManagerInterface::class);

// Actually map objects.
$mapperManager->map($databaseItem, $responseItem);