Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Fixed FormAnnotationBuilderFactory::injectFactory() for zend-servicemanager v2 #235

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Service/FormAnnotationBuilderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private function injectFactory(
AnnotationBuilder $annotationBuilder
) {
if ($formElementManager instanceof FormElementManagerV2Polyfill) {
$formElementManager->injectFactory($annotationBuilder, $container);
$formElementManager->injectFactory($annotationBuilder, $formElementManager);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would the formElementManager inject itself? I still dont get the meaning of this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The v3 implementation is therefore passing the real container.
You totally irritated me on this now 🙈

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a difference in how plugin managers work between version 2 and version 3.

In version 2, plugin managers pass themselves as the $container/$serviceLocator argument to factories and initiailizers. The idea at the time was to keep the plugin managers scoped; they would know nothing about the application-level services. However, we quickly realized this was problematic: most of the time, particularly with custom plugins, you need to access application-level services, such as the database connection, repositories, etc. So we made the plugin managers ServiceLocatorAware, so they would be injected with the parent (application) plugin manager, allowing plugin factories and initializers access to those services.

When we refactored the component for v3, we took this into consideration, and decided that plugin managers should be injected with the parent "context" (usually the application-level service manager), and that the parent context should be passed to plugin factories and initializers. This reduces the amount of boilerplate necessary for the vast majority of these classes, as it addresses the most typical use case.

Obviously, however, that has also meant some interesting migration issues when trying to provide both forwards compatibility with v3 implementations, and backwards compatibility with v2. You just stumbled upon one of the worst. 😁

Copy link
Member

@boesing boesing Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we refactored the component for v3, we took this into consideration, and decided that plugin managers should be injected with the parent "context" (usually the application-level service manager), and that the parent context should be passed to plugin factories and initializers. This reduces the amount of boilerplate necessary for the vast majority of these classes, as it addresses the most typical use case.

Makes sense, I dont think that anyone wants create another Controller in a ControllerFactory 😁.

Thanks for your patience and for those great insights of what was changed, e.g.

return;
}

Expand Down
2 changes: 1 addition & 1 deletion test/Service/FormAnnotationBuilderFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function testInjectFactoryInCorrectOrderV2()
->method('injectFactory')
->with($this->callback(function ($annotationBuilder) {
return $annotationBuilder instanceof AnnotationBuilder;
}), $serviceLocator);
}), $mockElementManager);

$sut = new FormAnnotationBuilderFactory();
$sut->createService($serviceLocator);
Expand Down