Custom factory with adapter bundle #72

Open
phillipsnick opened this Issue Aug 23, 2016 · 2 comments

Comments

Projects
None yet
3 participants
@phillipsnick

phillipsnick commented Aug 23, 2016

I'm trying to extend the Redis Factory to customise this to my needs. As suggested here: #71 (comment)

Given that a factory is a service I'd assume I should be able to define my own factory which extends AbstractAdapterFactory. But looks like the priorities in which Symfony Dependency Injection is loading the bundles prevents it from using a custom factory.

In the simplest terms here's what I have done, I'm just using Redis as an example here to try explain the issue.

src/CacheBundle/DependencyInjection/CacheExtension.php

class CacheExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('services.yml');
    }
}

src/CacheBundle/Resources/config/services.yml

services:
    cache.factory.test:
        class: CacheBundle\Factory\TestFactory

src/CacheBundle/Factory/TestFactory.php

class TestFactory extends AbstractAdapterFactory
{
    protected static $dependencies = [
        ['requiredClass' => 'Cache\Adapter\Redis\RedisCachePool', 'packageName' => 'cache/redis-adapter'],
    ];

    public function getAdapter(array $config)
    {
        // $client = some magic creating the Redis instance...

        $pool = new RedisCachePool($client);

        if (null !== $config['pool_namespace']) {
            $pool = new NamespacedCachePool($pool, $config['pool_namespace']);
        }

        return $pool;
    }

    protected static function configureOptionResolver(OptionsResolver $resolver)
    {
        parent::configureOptionResolver($resolver);

        $resolver->setDefaults(
            [
                'host'           => '127.0.0.1',
                'port'           => '6379',
                'pool_namespace' => null,
            ]
        );

        $resolver->setAllowedTypes('host', ['string']);
        $resolver->setAllowedTypes('port', ['string', 'int']);
        $resolver->setAllowedTypes('pool_namespace', ['string', 'null']);
    }
}

Then inside the applications config.yml I have the following setup

...
cache_adapter:
    providers:
        test:
            factory: 'cache.factory.test'
...

AppKernel.php

    public function registerBundles()
    {
        return array(
            // ...
            new CacheBundle\CacheBundle(),
            new Cache\AdapterBundle\CacheAdapterBundle(),
            new Cache\CacheBundle\CacheBundle(),
            // ...
        );
    }

All this results in

The service definition "cache.factory.test" does not exist.

Haven't worked at this low level in Symfony for a few months so might be missing something obvious here.

If I drop my services.yml contents into vendor/cache/adapter-bundle/Resources/config/services.yml it works perfectly, as this is all loaded in preperation for factory creation here: https://github.com/php-cache/adapter-bundle/blob/master/src/DependencyInjection/CacheAdapterExtension.php#L54

@lunetics

This comment has been minimized.

Show comment
Hide comment
@lunetics

lunetics Aug 26, 2016

Just was there at the same point. I think the factory stuff should be done in a compilerpass, where afaik all services (definitions) are available, not only the ones defined in the bundle services.yml

Just was there at the same point. I think the factory stuff should be done in a compilerpass, where afaik all services (definitions) are available, not only the ones defined in the bundle services.yml

@mho79

This comment has been minimized.

Show comment
Hide comment
@mho79

mho79 Apr 24, 2018

Anyone had any success doing this? Adding your own factory in a compiler pass

mho79 commented Apr 24, 2018

Anyone had any success doing this? Adding your own factory in a compiler pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment