auryn
auryn copied to clipboard
Wip separate injector contexts rebase
Although the current use of the extra args in Injector::execute() and Injector::make() are powerful, they are also dangerous.
They can lead to 'surprising' behaviour where data is shared inappropriately:
public function testWhySeparationIsNeeded()
{
$injector = new Injector();
$message = "shared instance has one off message";
// Declare a class as shared
$injector->share(SharedClassInInjector::class);
// Create an instance with one-off variables. The object is created.
$obj1 = $injector->make(SharedClassInInjector::class, [':message' => $message]);
// Create another instance... but as it is shared, the previous
// 'one-off' message is used.
$obj2 = $injector->make(SharedClassInInjector::class, [':message' => "Surprise!"]);
$this->assertSame($message, $obj1->getMessage());
$this->assertSame($message, $obj2->getMessage());
}
by allowing a separate context/injector to be created, the correct behaviour can be done by defining things that should't be shared, on the separated context.
Note, this doesn't prevent users from accidentally sharing data inappropriately.
$separate_injector = $injector->separateContext();
$injector->defineParam('message', $message);
The $separate_injector
would still be able to access that message. It only makes it possible to not do it.
API and names are not super great currently. Open to improvement on them.
Also, if someone is separating a context, they are probably going to do something with it very soon, so we could make it possible to pass in shares, defines etc.
Forgot to say, this could lead to the deprecation and eventually removal of the args for Injector:execute() + Injector:make(), which would give a small performance benefit due to the fewer cases of how to make stuff.
But there's no rush on that...