This repository has been archived by the owner on Feb 6, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch fixes alias resolution for version 2 to ensure (a) forwards compatibility with version 3, and (b) proper resolution of aliases with regards to services resolved by abstract factories. The original report in #66 was that doing the following did not work correctly: ```php $sm->setAlias('foo', InvokableObject::class); $sm->setFactory(InvokableObject::class, InvokableFactory::class); $result = $sm->get('foo'); ``` When the above code was executed, `InvokableFactory::createService()` was receiving arguments that it could not use, and thus raising an exception. On inspection, what I discovered was that the `$cName` provided as a normalized version of the resolved alias — and due to normalization, would not resolve to a fully qualified class name. This was due to the fact that the SM was storing a normalized version of the alias target. As such, the patch does the following: - Alias targets are no longer canonicalized in the internal `$aliases` array. This means that circular detection must canonicalize the targets for purposes of comparison when iterating aliases. It also means that when an alias is resolved, the name returned is the name as registered with the alias — which becomes important when considering fully qualified class names. - `get()` now resets the `$name` to the *resolved alias target* if an alias was detected. Combined with the above change, this means that factories and abstract factories now receive the resolved alias target as the requested name, and its canonicalized version as the `$cName`. One test broke with this change: `testGetAbstractFactoryWithAlias()`. Previously, it read as follows: ```php public function testGetAbstractFactoryWithAlias() { $this->serviceManager->addAbstractFactory('ZendTest\ServiceManager\TestAsset\FooAbstractFactory'); $this->serviceManager->setAlias('foo', 'ZendTest\ServiceManager\TestAsset\FooAbstractFactory'); $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $this->serviceManager->get('foo')); } ``` My assertion is that the test expectation is incorrect. The resolved alias of 'foo' is `ZendTest\ServiceManager\TestAsset\FooAbstractFactory`, *which that same abstract factory cannot resolve!* The behavior when retrieving a service via alias should be identical to fetching the alias target (which is the case with version 3). As such, this test rewrites the test to demonstrate what I consider the intended expectation: ```php public function testGetAbstractFactoryWithAlias() { $expected = new TestAsset\Foo; $abstractFactory = $this->prophesize(AbstractFactoryInterface::class); $abstractFactory->canCreateServiceWithName( $this->serviceManager, 'foo', 'Foo' )->willReturn(true); $abstractFactory->createServiceWithName( $this->serviceManager, 'foo', 'Foo' )->willReturn($expected); $this->serviceManager->addAbstractFactory($abstractFactory->reveal()); $this->serviceManager->setAlias('bar', 'Foo'); $this->assertSame($expected, $this->serviceManager->get('bar')); } ```
- Loading branch information