Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[DependencyInjection] XmlDumper/YamlDumper does not dump scope hierarchy #8539

Closed
jaypea opened this Issue · 5 comments

4 participants

@jaypea

Hi,

i'm using the DI Component Standalone in a bigger project and recently got an interesting ScopeCrossingInjectionException. After digging into the problem i found its my usage of dumpers and ContainerBuilders and Annotations.

Here is what i do:

    $sca = new DI\ContainerBuilder();
    $annotloader = new MyAnnotationLoader($sca);
    $annotloader->load(ROOT . 'src');
    $dumper = new DI\Dumper\XmlDumper($sca);
        file_put_contents(ROOT . 'cache/annotatedinc.xml', $dumper->dump());

        $service_container = new DI\ContainerBuilder();
    $locator = new SfConfig\FileLocator(array(
        ROOT . 'config/',
        ROOT . 'cache/',
    ));
    $xmlloader = new DI\Loader\XmlFileLoader($service_container, $locator);
    $resolver = new SfConfig\Loader\LoaderResolver(array($xmlloader));
    $xmlloader->setResolver($resolver);
    $xmlloader->load(ROOT . 'config/container.xml');
    $service_container->compile();
    $dumper = new DI\Dumper\PhpDumper($service_container);

container.xml might look like:

    <imports>
        <import resource="annotatedinc.xml"/>
        <import resource="mainservices.xml"/>
               <!-- more imports from other config files ... -->
    </imports>

now, to the interesting part.

    $sca->addScope(new DI\Scope('request', 'container'));
    $definition = new Definition('someservice');
    $definition->setScope('request');
    $sca->setDefinition('someservice', $definition);

when dumping this $sca instance, the definitions scope is dumped in the node.
But there is no reference of the scope itself which defines the parent of the given scope.
When loading this XML file later with the $service_container ContainerBuilder it sets the scope of the definition but does not add the Scope to the ContainerBuilder, the necessary information is not there.

My workaround currently is:

    $used_scopes = $sca->getScopes();
    foreach ($used_scopes as $name => $parentName) {
        $service_container->addScope(new DI\Scope($name, $parentName));
    }

is this setup too strange or does it makes sense to extend the xml schema to dump and load also the used scopes from ContainerBuilder?

I would provide a PR, if this is a feasible approach to this problem.

@stof
Collaborator

scopes cannot be registered through the XML config file. This is why the dumped XML file does not contain them.

@jaypea

thank you for summing up my problem.
my question now would be, would it make sense to add this missing feature?

<service id="myservice" scope="notRegisteredScope" class="someServiceClass" />

if the ContainerBuilder finds this XML Service Definition, what should it do?

I would suggest to extend the XML Schema to include the Scopes like this:

<container>
    <scopes>
        <scope name="notRegisteredScope" parent="anotherScope" />
        <scope name="anotherScope" parent="container" />
    </scopes>
    <services>
        <service id="myservice" scope="notRegisteredScope" class="someServiceClass" />
    </services>
</container>

hope i made my problem and suggestion more clear now.

@jakzal
Collaborator

@jaypea I might have misunderstood your use case, but you probably should dump the container to php class and use that, just like Symfony does.

As @fabpot mentioned in #8590, XML and YAML files purpose is to describe services. Scopes are the domain of container.

Since #8590 was closed, I think we can close this one as well.

@jakzal
Collaborator

@jaypea any feedback?

@fabpot
Owner

Closing this issue for the reasons I explained in the PR. Moreover, scopes are probably a feature that will be removed at some point (at least in its current shape) as we don't really rely on it anymore (as of 2.4, the request scope is only needed for BC reasons thanks to the request stack service and the prototype one is not used in the core -- and can be replaced by a flag like it was done in the good old days of Symfony pre-2.0).

@fabpot fabpot closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.