简体   繁体   中英

Pimple's ServiceProvider not getting options on register

I have had a fair amount of working with Silex and its dependency handling mechanism through Pimple. I am trying to extend the whole dependency injection thing to be able to resolve classes and/or instances through Pimple's container (Dependency Inversion).

I realize there are libraries out there that can allow me to achieve this but what a better way to learn if not re-inventing the wheel or something along those lines?

namespace Agnostic\DependencyInversion\Provider;

use Pimple\ServiceProviderInterface;
use Pimple\Container;

class ContainerBindingsServiceProvider implements ServiceProviderInterface
{
    public function register(Container $container)
    {
        if( !isset($container['context.bindings']) ){
            throw new \Exception("Missing bindings for the Application Context.");
        }
    }
}

In my test file I have two methods as of yet that first tests to see if an exception is thrown when the value that is being checked is not available.

This works the same as the exception that is thrown when trying to resolve an identifier that has not yet been registered.

namespace Agnostic\Test\ServiceProviderTestSuite;

use Agnostic\DependencyInversion\Provider\ContainerBindingsServiceProvider;
use Pimple\Container;

class ContainerBindingsServiceProviderTest extends \PHPUnit_Framework_TestCase
{
    public function testItThrowsExceptionIfNoBindingsSet()
    {
        try{

            $container = new Container();

            $container->register(new ContainerBindingsServiceProvider());

        }catch(\Exception $exc){

            $this->assertEquals($exc->getMessage(), "Missing bindings for the Application Context.");

            return;

        }

        $this->fail("Expected Exception has not been raised.");
    }

    public function testItContainesBindings()
    {
        $container = new Container();


        $container->register(new ContainerBindingsServiceProvider(), array('context.bindings' => (function(){
                    return include APP_DIR .'/config/bindings.php';
                })())
            );
    }
}

Initially I had the Container instance created within the setUp method of my test class and figured out this may be an issue even though I know that PHPUnit re-initializes everything that is there for each test method.

With the test results shown below I am left wondering as to what am I doing wrong.

PHPUnit 5.6.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.0.0
Configuration: C:\Users\luyandasiko\Documents\spikes\dependency-inversion\phpunit.xml

.E                                                                 2 / 2 (100%)

Time: 42 ms, Memory: 4.00MB

There was 1 error:

1)   Agnostic\Test\ServiceProviderTestSuite\ContainerBindingsServiceProviderTest::testItContainesBindings
Exception: Missing bindings for the Application Context.

C:\Users\luyandasiko\Documents\spikes\dependency-inversion\src\Provider\ContainerBindingsServiceProvider.php:13
C:\Users\luyandasiko\Documents\spikes\dependency-inversion\vendor\pimple\pimple\src\Pimple\Container.php:274
C:\Users\luyandasiko\Documents\spikes\dependency-inversion\dev\Test\ServiceProviderTestSuite\ContainerBindingsServiceProviderTest.php:35

ERRORS!
Tests: 2, Assertions: 1, Errors: 1.

The line on my second test function (see code below) just returns the array defined in my config nothing special thus the array could be manually made up it does not matter as I did that but couldn't get passed through this.

(function(){
    return include APP_DIR .'/config/bindings.php';
})()

I have looked at Siliex code base to see how the default service providers handle options but it seems I am missing something. Can somebody point me to the right direction as to what I could be missing with this?

So when I got home I spent sometime trying to figure out why I couldn't have my services providers inject passed parameters when registering them.

 $container-register(new \MyWorkSpace\ServiceProvider\SampleServiceProvider(), ['key' => 'val']);

When I access the container thereafter I should be able to query the container for the key identifier.

Below is how Pimple defines the register methods in its Container.

public function register(ServiceProviderInterface $provider, array $values = array())
{
    $provider->register($this);

    foreach ($values as $key => $value) {
        $this[$key] = $value;
    }

    return $this;
}

What I did to test my assertions is to change the code listing above to:

public function register(ServiceProviderInterface $provider, array $values = array())
{


    foreach ($values as $key => $value) {
        $this[$key] = $value;
    }

    $provider->register($this);

    return $this;
}

This for me worked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM