Using a different container

Hey guys!

In my Slim project, I’m trying to use a different container than the Slim one (League\Container\Container to be precise). Somehow, my Actions (the invokable route classes) get passed a Slim\Container though and I have no idea how/why.

My code (generalized):

<?php

$slimContainer = new Slim\Container();
$container = new League\Container\Container();

$container->delegate($slimContainer);

$app = new Slim\App($container);
$app->run();

And my action looks like this:

<?php

class Action
{
    private $container;

    public function __construct(Interop\Container\ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function __invoke(RequestInterface $request, ResponseInterface $response)
    {
        $response->getBody()->write('Test');

        return $response;
    }
}

If I var_dump the container in the invoke method, I get an instance of Slim\Container, which is odd and unexpected to me, but perhaps you can explain to me why this happens.

Thanks in advance!

maybe u can use “namespace”

When you create a Slim\Container, it creates a set of default services, including callableResolver. This default service is wired to the Slim container. Because the League container is set to delegate to the Slim container, the default callableResolver instance is used.

To make the callable resolver use the League container, register a callableResolver service that uses League container:

$slimContainer = new Slim\Container();
$container = new League\Container\Container();

$container->delegate($slimContainer);

// register a callableResolver that uses the League container instead of the Slim container
$container->add('callableResolver', new Slim\CallableResolver($container));

$app = new Slim\App($container);
$app->run();

$app = new Slim\App($container);

This may not be needed with Slim version 4, which is currently being developed.

Note that the action is only called with the container as the constructor argument if the action class cannot be found in the container. If you define the action class in the container or use autowiring, the container is not passed as a constructor argument.

Thanks a lot for your extensive reply, I got to more or less the same solution, but not nearly as clean. Will implement this in my application.

:grinning: