#Classes provided in a decorator are instantiated in each module

1 messages · Page 1 of 1 (latest)

unreal wind
slender socket
#

are you looking for a way to share the same instance of the guard between modules?

unreal wind
#

nono because i could set it as global for reaching this goal.
Its more like a question... why enanched stuff are not singleton like providers

slender socket
#

no ideia

#

this was a design decision made by Kamil, I guess

unreal wind
#

The only thing which came to my mind was the fact that decorated stuff are coming before runtime

#

so the ioc container is not ready yet

#

during the class definition decorators are going to run

#

when something is injected in a constructor, the class is already defined, and the decorator like a guard or a filter or whatever is decorating that class run much earlier

slender socket
#

well, if you don't treat guards as standard providers, you will get only one instance of the guard

unreal wind
#

expect to provide them as global, is discouraged to provide them as provider (its written in the documentation)

#

@unreal quarry could you please clarify this decision? thanks

gusty pier
#

I see where you're coming from, but enhacers looks for their dependencies in the module they're used. So if you used @UseGuards(MyGuard) in two different modules, you could technically get different dependencies and therefore not equivalent instances.

#

It is a strange and confusing design decisions, that enhancers don't act as providers and don't really belong to any module. It kind of breaks encapsulation, because you have to make their dependencies available in the consumer module. But it is what it is. Changing this behavior would be a major breaking change.

#

But because of that, it is not easy to share a single instance of an enhancer across modules (unless it is global)

#

You could theoretically make such an optimization to only instantiate enhancers per module, but I would assume the benefit of lower memory footprint is not worth the added complexity.

unreal wind
#

Currently, enhancers are instantiated per module when referenced by their class name as a token. However, in large projects, this can lead to excessive memory usage. The framework's core principle is modularity, enabling the sharing of singleton dependencies. This behavior with enhancers seems unusual.

This is likely because decorators run before dependency injection. For example, when declaring a guard for a controller class, you're adding logic during class declaration—before the class instance is created. Therefore, by the time the constructor runs, the decorator has already executed. Dependency injection cannot be used because dependency resolution hasn't yet begun.

This appears to be the main reason. It would be helpful if @unreal quarry could confirm.

unreal quarry
#

This was a deliberate design decision. If enhancers acted as providers, they would have to be declared as providers every single time they're being used, leading to a more boilerplate needed in order to bind them to a specific controller (or method). Also, they could be injected into other providers which makes even less sense.

Now, when it comes to the memory usage, even with over 500 modules and up to 10 enhancers per module (a highly unlikely scenario), the memory impact would be negligible. Since enhancers can inject providers, there’s no need to re-register their dependencies across every module. Note that if you annotate, let's say, 20 methods within a single module with the @UseGuards(AuthGuard) decorator, only one AuthGuard instance will be created.