Initial Code Commit

This commit is contained in:
Alan Bridgeman 2025-02-17 16:32:27 -06:00
parent fa1468245f
commit 28db152b87
24 changed files with 2691 additions and 2 deletions

View file

@ -0,0 +1,32 @@
# Automated Controller Loading with Child Controllers
While loading controllers automatically from a provided directory is an overall helpful feature in abbreviating the code for the end developer/user while maintaining a high level of flexibility. However, it does introduce a particular problem with child controllers.
## The Issue
The issue with a naive approach of just calling `setup` on all controllers we find in the designated directory (and it's subdirectories) is this would produce duplicate callbacks for the same route. This is because we would both call `setup` as we find the controllers but ALSO inside the `Controller` decorator for child controllers.
## The Solution Impact
However, to resolve this has meant multiple entire passes of all the found controllers which if there is a large amount of controllers could be pretty inefficient in a number of ways.
For instance, this means that parallelization of loading is limited to the initial loading rather than calling of `setup`
Another way, our particular solution to this issue, at least currently, precludes using any kind of greedy methodology which if we could use could make the loading significantly more efficient.
This is because we can't know that the parent controller (with the `ChildController` decorator) would be processed before any child controller is.
## The Solution
The following is the isolated code that addresses this particular issue
```typescript
// Get all controllers that have the child controller decorator
const controllersWithChildControllers = loadedControllers.filter(controller => Reflect.getMetadata('ChildController', controller) !== undefined);
// Get all those controllers that are designated as children controllers by parent controller
const childrenControllers = controllersWithChildControllers.map(controller => Reflect.getMetadata('ChildController', controller));
// Get the exclusive set of controllers that don't fit in the group of controllers with child controllers OR a child controller themselves
const controllersWithoutChildren = loadedControllers.filter(controller => !controllersWithChildControllers.includes(controller) && !childrenControllers.includes(controller));
// Take the list of controllers with child controllers and the list without children (that excludes children themselves)
// And forma a list that has all child controllers removed
const topLevelControllers = [...controllersWithChildControllers, ...controllersWithoutChildren];
```