-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[WIP][DependencyInjection] Add a new Syntax to define factories as callables. #9839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
just a random thought This will make setting factories easier, and so would also allow Expressions as factory, as it does not make sense to use service of class for this. But this is just random thought, so nothing concrete. |
the new API seems easier to use. However, the Definition now has 2 different factories stored in it, which can lead to weird state when manipulating it. the deprecated API should be reimplemented on top of the new API IMO, to make it only a BC layer |
I'm relatively sure this will lead to really weird edge cases. For example, if I set the factory to an object (not a service nor a class), than I will get a result for factoryMethod but neither factoryClass nor factoryService. Not sure everything outside out control can handle that. |
@realityking This case should be forbidden, because it will not be possible to dump the container if you pass an object |
@stof The dumpers already check for that and throw an exception if they encounter an object. Shouldn't this remain consistent? |
@@ -56,6 +57,34 @@ public function __construct($class = null, array $arguments = array()) | |||
} | |||
|
|||
/** | |||
* Sets a factory | |||
* | |||
* @param callable $callable A PHP callable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to support strings like 'class_name::method' or a service call like 'service_name.method_name' (both of which being supported elsewhere in the framework)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting with PHP 5.2.3 (no typo), class_name::method
should work just fine as they're valid PHP callable.
As for the service_name.method_name
syntax, I'd have to take a look how complex that'd be to do. Where else is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@realityking Actually, I made a typo, i meant service_name:method_name
. Support should be relatively easy as this would be converted to something like $container->get('service_name')->method_name()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't that create a fair amount ambiquity? What if I have a service and and a class with the same name?
I'll have to change this comment though, since it's not really a PHP callable I expect. It also accepts a Reference
or Definition
and a method name as an array.
That said, if we allow a plain service name instead of a reference we'll break the inlining and get the weird bug with private services again. The only solution to that would be to do the conversion at parse time - but than I don't know all the services and get back to the problem above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do see an ambiguity? It's :
, not ::
for service calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, didn't look careful enough.
With that information, would it be ok to do this at the parser level and only allow this syntax in YAML and XML but not when directly manipulating the Definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, support is only relevant for the YAML and XML formats.
@fabpot I added the If you think this is still worthwhile with just YAML support, than I'll add the same for configurators in a different pull request to keep them in sync. |
@fabpot Any feedback on using the short hand syntax only for YAML? I'd like to write the documentation to get this done. |
@fabpot Ping. I'd like to write the docs to get this done. |
@fabpot I know the ship has sailed for 2.5, but could you give me some feedback about the short hand syntax? (only for YAML or not at all) |
@@ -18,6 +18,11 @@ UPGRADE FROM 2.x to 3.0 | |||
`DebugClassLoader`. The difference is that the constructor now takes a | |||
loader to wrap. | |||
|
|||
### DependencyInjection | |||
|
|||
* The methods `setFactoryClass()`, `setFactoryMethod()` and `setFactoryService()`have been removed in favor of `setFactory`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be a space before "have been removed"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and setFactory()
(to be consistent?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, fixed.
@@ -65,6 +94,7 @@ public function __construct($class = null, array $arguments = array()) | |||
* @return Definition The current instance | |||
* | |||
* @api | |||
* @deprecated Deprecated since version 2.5, to be removed in 3.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since version 2.6
Don't know why this one slipped under the radar. I'm going to submit a new PR to fix some small things (mainly CS and updated to current master) -- see #12008. Thanks @realityking for this great work and sorry again for the delay. Can you submit a PR for the documentation? |
…ries as callables (realityking, fabpot) This PR was merged into the 2.6-dev branch. Discussion ---------- [DependencyInjection] Add a new Syntax to define factories as callables | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - From the original PR #9839: "This pull requests adds a new syntax to define factories based on the syntax for configurators. This is more flexible than the old syntax (factoryMethod and either of factoryClass or factoryService), as it also allows for functions as factories. Since the service is now a Reference to a Definition it also allows us to inline factories for a small performance improvement and better encapsulation. Lastly this prevents a bug where a private factory is simple removed because it's not referenced in the graph. I did not change any of the existing definitions (there's one use of a factory in FrameworkBundle) or automatically use the new internal representation when parsing YAML or XML definitions because this could introduce subtle B/C issues. " Commits ------- 187aeee fixed CS bd8531d added a new Syntax to define factories as callables.
Awesome, I already wrote this off. I'll see that I get to the docs on the weekend. |
This pull requests adds a new syntax to define factories based on the syntax for configurators. This is more flexible than the old syntax (factoryMethod and either of factoryClass or factoryService), as it also allows for functions as factories.
Since the service is now a Reference to a Definition it also allows us to inline factories for a small performance improvement and better encapsulation.
Lastly this prevents a bug where a private factory is simple removed because it's not referenced in the graph.
I did not change any of the existing definitions (there's one use of a factory in FrameworkBundle) or automatically use the new internal representation when parsing YAML or XML definitions because this could introduce subtle B/C issues.
There are still a few things left to do (see list below), I wanted a general thumbs up on the approach and the deprecation before I continue.
Todo: