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

Closed
jaypea opened this Issue Jul 22, 2013 · 5 comments

Comments

Projects
None yet
4 participants
@jaypea
Contributor

jaypea commented Jul 22, 2013

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

This comment has been minimized.

Show comment Hide comment
@stof

stof Jul 22, 2013

Member

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

Member

stof commented Jul 22, 2013

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

@jaypea

This comment has been minimized.

Show comment Hide comment
@jaypea

jaypea Jul 22, 2013

Contributor

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.

Contributor

jaypea commented Jul 22, 2013

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

This comment has been minimized.

Show comment Hide comment
@jakzal

jakzal Nov 30, 2013

Member

@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.

Member

jakzal commented Nov 30, 2013

@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

This comment has been minimized.

Show comment Hide comment
@jakzal

jakzal Dec 29, 2013

Member

@jaypea any feedback?

Member

jakzal commented Dec 29, 2013

@jaypea any feedback?

@fabpot

This comment has been minimized.

Show comment Hide comment
@fabpot

fabpot Dec 29, 2013

Member

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).

Member

fabpot commented Dec 29, 2013

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 Dec 29, 2013

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