Closed fredw closed 8 years ago
Hi @fredw -- this has been a subject of some discussion. Short version: calling get()
or newInstance()
locks the container automatically, because further modifications to $params
and $setters
after creating a concrete object instance are not honored. Thus, the container is locked to prevent making changes that won't be recognized.
Although the docs say the container will be locked after get/newInstance(), I went back and forth on how to prevent changes to the container that would not be honored. Perhaps the right thing to do is throw an exception when get/newInstance are called and the container is not locked.
To pre-empt one objection: yes, the container should be locked and prevent changes after initial setup. The idea is to do all setup work before creating any objects.
Thoughts?
Related issue https://github.com/auraphp/Aura.Di/issues/107 and discussion in groups https://groups.google.com/d/msg/auraphp/kOunjCihqe4/gLQtqNt6CwAJ
Now I understand the reason of lock, but I have some problems that I don't know how to handle with. I have just read the issue #107, but still don't know how to act.
I'm using Slim as router and I'm implementing middlewares to overwrite the 'errorHandler
' service. Some like this:
$container = (new Aura\Di\ContainerBuilder)->newInstance();
$app = new Slim\App($container);
$app->add(new MyMiddleware($app));
// Routes - Iternally Slim calls $this->container->get('router'),
// which causes the container to be locked
$app->get('/', function () { /* ... */ });
// Here all middlewares are invoked
$app->run();
Here is my middleware class:
class MyMiddleware
{
private $app;
public function __construct(Slim\App $app)
{
$this->app = $app;
}
public function __invoke($req, $resp, $next)
{
// ...
$container = $this->app->getContainer();
// Here the exception is thrown, because the container is locked
$container->set('errorHandler', function () {});
// ...
}
}
I realy would like to use Aura.DI, replacing the Pimple which is the standard Slim container. Sorry for post this particular type of question here, but I would like to know the best way to handle this situation.
@fredw move $container->set('errorHandler', function () {});
to outside.
So you can set the container definitions before calling it. That means
$container = (new Aura\Di\ContainerBuilder)->newInstance();
// move all container definitions here
$app = new Slim\App($container);
You don't need to set an error handler on execution MyMiddleware
.
I suggest you to visit http://auraphp.com/packages/Aura.Di/config.html and see all examples.
Thank you.
Yes, @harikt has the right answer here. The intent behind Aura.Di is to use it as a Dependency Injection container, not as a service locator. Among other things, that means you configure the container in advance, and then pull objects out of it. Essentially that means putting your configurations in a config section of the application, not mixing configuration and creation.
Does that help at all?
Thank you for response. I had some misconceptions about Dependency Injection and Service Locator. Now I can understand what I'm doing wrong.
Hi,
I have a problem/doubt about locked container, I don't understand the functioning of this issue. I'm trying to
set
after call aget
and an exception is thrown:I'm trying to do something like this: