Issue
Working with Symfony 5.3 I would like to find all classes within the project which use a custom annotation @MyAnnotation
.
While I have found countless tutorials and a lot of information about annotations, they all only show how to check if a given object or method uses some annotation. For example it is no problem to use a kernel event subscriber to test if the current controller uses a annotation or not.
But I was not able to find a way, to automatically find / discover all classes which use a given annotation. I assume that Doctrine itself does the same to find all entities which use its @Entity
annotation. But how is this done?
I tried to check the Doctrine code to see how hit works, but I did not found out.
Is there some build in features? Or is there some giveMeAllClassesInProject()
method I could use to test each class manually?
Traversing all classes within the project would not be practical. I do not have to actively tell Doctrine that MyBundle
is installed in the project and that it can find its entities at /vendor/me/my-bundle/src/Entity
but Doctrine does find these entities.
Of course the src/Entity/
part is standard and pretty sure belongs to the Doctrines default configuration, but Doctrine still need to know which bundles are installed, where to find them, where to find the project src/
dir, etc. So there needs to be be some giveMeAlleSrcDirsInProject()
method or something in this direction, doesn't it?
Additionally even if Symfony would deliver all src/
dirs, traversing them and checking all entity classes for some annotation on every request would be pretty inefficient. So this information is surely cached somehow. But when is this information gathered, etc.
In short: Is there any standard procedure on how to implement annotations like @Entity
?
Solution
You would need to traverse all classes that exist in a project, and check each one if they are annotated one way or another.
Usually that's not practical, so you would have (like Doctrine or Symfony do) configuration settings telling your code WHERE to look for those classes.
Then you scan only those files, and that's that.
Doctrine knows which bundles are installed and where to look thanks to the Doctrine Symfony Bundle, and by default looks always in the same places for defined mappings. But even the, it only look in specific directories within those bundles (scanning those directories), it doesn't "know about all defined classes".
Using something like get_declared_classes()
wouldn't work, since not all classes are necessarily read at a given time for a given request. And some/many classes will be loaded that are irrelevant for your use case. Same with trying to rely on other system that did something similar and left some kind of cache behind: since those libraries/packages are looking for different things than you, their results might not be relevant.
Even with configuration telling the application where to look, this is typically not done at runtime on each request, since it would be too expensive. Packages/Frameworks as Doctrine or Symfony do this once and "cache" the results in different kinds of configuration files and proxy classes.
For traversing directories and checking files therein, maybe you can use Symfony Finder. You are bound to find many examples online. The exact implementation would depend on different assumptions made by your application.
Answered By - yivi
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.