Skip to content

Commit

Permalink
add to DI
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Oct 14, 2024
1 parent 10693ab commit a5243d6
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 74 deletions.
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TODO

* Cache should skip unalterable objects
* change unalterabledeterminer to a service
* mechanism to add methods to collector
51 changes: 43 additions & 8 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\Implementation\CachingObjectToObjectMetadataFactory;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\Implementation\ObjectToObjectMetadataFactory;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\Implementation\ProxyResolvingObjectToObjectMetadataFactory;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessor\DefaultObjectProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessor\CachingPropertyProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessor\DefaultPropertyProcessorFactory;
use Rekalogika\Mapper\TransformerRegistry\Implementation\CachingTransformerRegistry;
use Rekalogika\Mapper\TransformerRegistry\Implementation\TransformerRegistry;
use Rekalogika\Mapper\TypeResolver\Implementation\CachingTypeResolver;
Expand Down Expand Up @@ -227,10 +230,7 @@
->set(ObjectToObjectTransformer::class)
->args([
'$objectToObjectMetadataFactory' => service('rekalogika.mapper.object_to_object_metadata_factory'),
'$propertyMapperLocator' => tagged_locator('rekalogika.mapper.property_mapper'),
'$subMapperFactory' => service('rekalogika.mapper.sub_mapper.factory'),
'$proxyFactory' => service('rekalogika.mapper.proxy.factory'),
'$propertyAccessor' => service(PropertyAccessorInterface::class),
'$objectProcessorFactory' => service('rekalogika.mapper.transformer_processor.object_processor_factory'),
])
->tag('rekalogika.mapper.transformer', ['priority' => -900]);

Expand Down Expand Up @@ -273,10 +273,7 @@
)
->args([
'$objectToObjectMetadataFactory' => service('rekalogika.mapper.object_to_object_metadata_factory'),
'$propertyMapperLocator' => tagged_locator('rekalogika.mapper.property_mapper'),
'$subMapperFactory' => service('rekalogika.mapper.sub_mapper.factory'),
'$proxyFactory' => service('rekalogika.mapper.proxy.factory'),
'$propertyAccessor' => service(PropertyAccessorInterface::class),
'$objectProcessorFactory' => service('rekalogika.mapper.transformer_processor.object_processor_factory'),
]);

# mapping cache warmer
Expand Down Expand Up @@ -382,6 +379,44 @@
service($createCache($services, 'transformer_registry')),
]);

# transformer processor, object processor factory

$services
->set(
'rekalogika.mapper.transformer_processor.object_processor_factory',
DefaultObjectProcessorFactory::class,
)
->args([
'$propertyMapperLocator' => tagged_locator('rekalogika.mapper.property_mapper'),
'$subMapperFactory' => service('rekalogika.mapper.sub_mapper.factory'),
'$proxyFactory' => service('rekalogika.mapper.proxy.factory'),
'$propertyAccessor' => service(PropertyAccessorInterface::class),
'$propertyProcessorFactory' => service('rekalogika.mapper.transformer_processor.property_processor_factory'),
]);

# transformer processor, property processor factory

$services
->set(
'rekalogika.mapper.transformer_processor.property_processor_factory',
DefaultPropertyProcessorFactory::class,
)
->args([
'$propertyAccessor' => service(PropertyAccessorInterface::class),
'$subMapperFactory' => service('rekalogika.mapper.sub_mapper.factory'),
'$propertyMapperLocator' => tagged_locator('rekalogika.mapper.property_mapper'),
]);

$services
->set(
'rekalogika.mapper.transformer_processor.property_processor_factory.caching',
CachingPropertyProcessorFactory::class,
)
->decorate('rekalogika.mapper.transformer_processor.property_processor_factory')
->args([
service('.inner'),
]);

# sub mapper

$services
Expand Down
50 changes: 39 additions & 11 deletions src/MapperFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
use Rekalogika\Mapper\Transformer\MetadataUtil\MetadataUtilLocator;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\ObjectToObjectMetadataFactoryInterface;
use Rekalogika\Mapper\Transformer\TransformerInterface;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessor\DefaultObjectProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessorFactoryInterface;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessor\CachingPropertyProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessor\DefaultPropertyProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessorFactoryInterface;
use Rekalogika\Mapper\TransformerRegistry\Implementation\TransformerRegistry;
use Rekalogika\Mapper\TransformerRegistry\TransformerRegistryInterface;
use Rekalogika\Mapper\TypeResolver\Implementation\CachingTypeResolver;
Expand Down Expand Up @@ -197,6 +202,10 @@ class MapperFactory

private ?ProxyFactoryInterface $proxyFactory = null;

private ?ObjectProcessorFactoryInterface $objectProcessorFactory = null;

private ?PropertyProcessorFactoryInterface $propertyProcessorFactory = null;

private ?MappingCommand $mappingCommand = null;

private ?TryCommand $tryCommand = null;
Expand Down Expand Up @@ -403,17 +412,10 @@ protected function getNullTransformer(): TransformerInterface

protected function getObjectToObjectTransformer(): TransformerInterface
{
if (null === $this->objectToObjectTransformer) {
$this->objectToObjectTransformer = new ObjectToObjectTransformer(
objectToObjectMetadataFactory: $this->getObjectToObjectMetadataFactory(),
propertyMapperLocator: $this->getPropertyMapperLocator(),
subMapperFactory: $this->getSubMapperFactory(),
proxyFactory: $this->getProxyFactory(),
propertyAccessor: $this->getPropertyAccessor(),
);
}

return $this->objectToObjectTransformer;
return $this->objectToObjectTransformer ??= new ObjectToObjectTransformer(
$this->getObjectToObjectMetadataFactory(),
$this->getObjectProcessorFactory(),
);
}

protected function getObjectToStringTransformer(): TransformerInterface
Expand Down Expand Up @@ -899,6 +901,32 @@ protected function getProxyFactory(): ProxyFactoryInterface
return $this->proxyFactory;
}

//
// transformer processor
//

protected function getObjectProcessorFactory(): ObjectProcessorFactoryInterface
{
return $this->objectProcessorFactory ??= new DefaultObjectProcessorFactory(
propertyMapperLocator: $this->getPropertyMapperLocator(),
subMapperFactory: $this->getSubMapperFactory(),
proxyFactory: $this->getProxyFactory(),
propertyAccessor: $this->getPropertyAccessor(),
propertyProcessorFactory: $this->getPropertyProcessorFactory(),
);
}

protected function getPropertyProcessorFactory(): PropertyProcessorFactoryInterface
{
return $this->propertyProcessorFactory ??= new CachingPropertyProcessorFactory(
new DefaultPropertyProcessorFactory(
propertyAccessor: $this->getPropertyAccessor(),
subMapperFactory: $this->getSubMapperFactory(),
propertyMapperLocator: $this->getPropertyMapperLocator(),
),
);
}

//
// command
//
Expand Down
24 changes: 6 additions & 18 deletions src/Transformer/Implementation/ObjectToObjectTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,19 @@

namespace Rekalogika\Mapper\Transformer\Implementation;

use Psr\Container\ContainerInterface;
use Rekalogika\Mapper\CacheWarmer\WarmableMainTransformerInterface;
use Rekalogika\Mapper\CacheWarmer\WarmableObjectToObjectMetadataFactoryInterface;
use Rekalogika\Mapper\CacheWarmer\WarmableTransformerInterface;
use Rekalogika\Mapper\Context\Context;
use Rekalogika\Mapper\Exception\InvalidArgumentException;
use Rekalogika\Mapper\Proxy\ProxyFactoryInterface;
use Rekalogika\Mapper\SubMapper\SubMapperFactoryInterface;
use Rekalogika\Mapper\Transformer\Exception\NotAClassException;
use Rekalogika\Mapper\Transformer\MainTransformerAwareInterface;
use Rekalogika\Mapper\Transformer\MainTransformerAwareTrait;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\ObjectToObjectMetadataFactoryInterface;
use Rekalogika\Mapper\Transformer\TransformerInterface;
use Rekalogika\Mapper\Transformer\TypeMapping;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessor\DefaultObjectProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessorFactoryInterface;
use Rekalogika\Mapper\Util\TypeFactory;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyInfo\Type;

final class ObjectToObjectTransformer implements
Expand All @@ -40,25 +35,18 @@ final class ObjectToObjectTransformer implements
{
use MainTransformerAwareTrait;

private ?ObjectProcessorFactoryInterface $objectProcessorFactory = null;
private ?ObjectProcessorFactoryInterface $objectProcessorFactoryWithMainTransformer = null;

public function __construct(
private ObjectToObjectMetadataFactoryInterface $objectToObjectMetadataFactory,
private ContainerInterface $propertyMapperLocator,
private SubMapperFactoryInterface $subMapperFactory,
private ProxyFactoryInterface $proxyFactory,
private PropertyAccessorInterface $propertyAccessor,
private readonly ObjectToObjectMetadataFactoryInterface $objectToObjectMetadataFactory,
private readonly ObjectProcessorFactoryInterface $objectProcessorFactory,
) {}

private function getObjectProcessorFactory(): ObjectProcessorFactoryInterface
{
return $this->objectProcessorFactory ??= new DefaultObjectProcessorFactory(
mainTransformer: $this->getMainTransformer(),
propertyMapperLocator: $this->propertyMapperLocator,
subMapperFactory: $this->subMapperFactory,
proxyFactory: $this->proxyFactory,
propertyAccessor: $this->propertyAccessor,
);
return $this->objectProcessorFactoryWithMainTransformer
??= $this->objectProcessorFactory
->withMainTransformer($this->getMainTransformer());
}

#[\Override]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,42 @@
namespace Rekalogika\Mapper\TransformerProcessor\ObjectProcessor;

use Psr\Container\ContainerInterface;
use Rekalogika\Mapper\MainTransformer\MainTransformerInterface;
use Rekalogika\Mapper\Proxy\ProxyFactoryInterface;
use Rekalogika\Mapper\SubMapper\SubMapperFactoryInterface;
use Rekalogika\Mapper\Transformer\MainTransformerAwareTrait;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\ObjectToObjectMetadata;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessorFactoryInterface;
use Rekalogika\Mapper\TransformerProcessor\ObjectProcessorInterface;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessor\DefaultPropertyProcessorFactory;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessorFactoryInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

/**
* @internal
*/
final readonly class DefaultObjectProcessorFactory implements ObjectProcessorFactoryInterface
final class DefaultObjectProcessorFactory implements ObjectProcessorFactoryInterface
{
private PropertyProcessorFactoryInterface $propertyProcessorFactory;
use MainTransformerAwareTrait;

public function __construct(
private MainTransformerInterface $mainTransformer,
private ContainerInterface $propertyMapperLocator,
private SubMapperFactoryInterface $subMapperFactory,
private ProxyFactoryInterface $proxyFactory,
private PropertyAccessorInterface $propertyAccessor,
) {
$this->propertyProcessorFactory = new DefaultPropertyProcessorFactory(
propertyAccessor: $this->propertyAccessor,
mainTransformer: $this->mainTransformer,
subMapperFactory: $this->subMapperFactory,
propertyMapperLocator: $this->propertyMapperLocator,
);
}
private readonly ContainerInterface $propertyMapperLocator,
private readonly SubMapperFactoryInterface $subMapperFactory,
private readonly ProxyFactoryInterface $proxyFactory,
private readonly PropertyAccessorInterface $propertyAccessor,
private readonly PropertyProcessorFactoryInterface $propertyProcessorFactory,
) {}

public function getObjectProcessor(
ObjectToObjectMetadata $metadata,
): ObjectProcessorInterface {
return new ObjectProcessor(
metadata: $metadata,
mainTransformer: $this->mainTransformer,
mainTransformer: $this->getMainTransformer(),
propertyMapperLocator: $this->propertyMapperLocator,
subMapperFactory: $this->subMapperFactory,
proxyFactory: $this->proxyFactory,
propertyAccessor: $this->propertyAccessor,
propertyProcessorFactory: $this->propertyProcessorFactory,
propertyProcessorFactory: $this->propertyProcessorFactory
->withMainTransformer($this->getMainTransformer()),
);
}
}
6 changes: 3 additions & 3 deletions src/TransformerProcessor/ObjectProcessor/ObjectProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ private function generateConstructorArguments(
try {
/** @var mixed $targetPropertyValue */
[$targetPropertyValue,] = $this->propertyProcessorFactory
->getPropertyMapper($propertyMapping)
->getPropertyProcessor($propertyMapping)
->transformValue(
source: $source,
target: null,
Expand Down Expand Up @@ -430,7 +430,7 @@ private function readSourceAndWriteTarget(
): object {
foreach ($propertyMappings as $propertyMapping) {
$target = $this->propertyProcessorFactory
->getPropertyMapper($propertyMapping)
->getPropertyProcessor($propertyMapping)
->readSourcePropertyAndWriteTargetProperty(
source: $source,
target: $target,
Expand All @@ -449,7 +449,7 @@ private function readSourceAndWriteTarget(
$propertyMapping = $propertyMappings[$property];

$target = $this->propertyProcessorFactory
->getPropertyMapper($propertyMapping)
->getPropertyProcessor($propertyMapping)
->writeTargetProperty(
target: $target,
value: $value,
Expand Down
3 changes: 2 additions & 1 deletion src/TransformerProcessor/ObjectProcessorFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@

namespace Rekalogika\Mapper\TransformerProcessor;

use Rekalogika\Mapper\Transformer\MainTransformerAwareInterface;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\ObjectToObjectMetadata;

/**
* @internal
*/
interface ObjectProcessorFactoryInterface
interface ObjectProcessorFactoryInterface extends MainTransformerAwareInterface
{
public function getObjectProcessor(
ObjectToObjectMetadata $metadata,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\TransformerProcessor\PropertyProcessor;

use Rekalogika\Mapper\Transformer\MainTransformerAwareTrait;
use Rekalogika\Mapper\Transformer\ObjectToObjectMetadata\PropertyMapping;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessorFactoryInterface;
use Rekalogika\Mapper\TransformerProcessor\PropertyProcessorInterface;

/**
* @internal
*/
final class CachingPropertyProcessorFactory implements PropertyProcessorFactoryInterface
{
use MainTransformerAwareTrait;

/**
* @var array<string,PropertyProcessorInterface> $cache
*/
private array $cache = [];

public function __construct(
private readonly PropertyProcessorFactoryInterface $decorated,
) {}

public function getPropertyProcessor(
PropertyMapping $metadata,
): PropertyProcessorInterface {
$id = $metadata->getId();

return $this->cache[$id] ??= $this->decorated
->withMainTransformer($this->getMainTransformer())
->getPropertyProcessor($metadata);
}
}
Loading

0 comments on commit a5243d6

Please sign in to comment.