-
Notifications
You must be signed in to change notification settings - Fork 294
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
Decorate does not work if inside fx.Module and Populate is called from outside Module #1222
Comments
Hey @CTrando, fx.Decorate are scoped to the deepest Fx module inside which the decorator was provided. In case 2, that's the root scope which is why the decoration works. |
In the first case, shouldn't the decorator apply to the provide statement because they're in the same module? My expectation would be that a module provides a given type, and any decorators inside that module would run as normal if necessary to provide that type, is my understanding incorrect? |
In the example above, fx.Populate is in the root scope not the scope of the Module where fx.Decorate is called. Moving fx.Populate into the Module where fx.Decorate is called should pass the test. |
You're right, the test does pass! So if I had a module that exposed a type, where that type was provided and decorated inside the module, how would I go about viewing that type from outside the module? Even if I did something like:
This fails too - the decorator changes don't appear outside the module. From what I'm seeing, it means that decorators on types are local to a given module, and their changes don't appear to any caller outside the module that references those types. Is that intentional? |
Hey @CTrando - yes, this is intentional and expected behavior. Take a look at https://pkg.go.dev/go.uber.org/fx#hdr-Decorator_scope. I think the idea is that a decorator in some small nested subscope shouldn't be able to just completely hijack some value for the entire application. That said, is there something preventing you from using your decorator at a higher-level scoping such that it applies everywhere you want it to? |
Ah, I see, in that documentation it doesn't matter where the
There is nothing preventing me from using decorators at a higher scope, and that's what I ended up doing, I was just curious about this. I think I was just confused at why decorators seemed special here, I viewed them as a piece of the module to be executed. For example:
This makes sense to me, if there's a decorator in a module that affects a type defined outside the module. But for decorators on types inside the module, I find it reasonable that decorators would still run, and that the type is not "complete" until those decorators have run. Perhaps my understanding of modules is incorrect - from these docs,
I was considering the decorator to be part of that self-contained functionality, it's still a bit surprising to me that its side effects are not considered outside the module. I agree that this seems intentional, although I wonder if this aligns with the idea of an |
Describe the bug
First, we can:
fx.Module
A
inside the moduleA
inside the modulefx.Module
, populate typeA
The result is that the decorate function would not have been applied.
To Reproduce
I have a testcase to reproduce this:
I expect that the decorate statement would have run to replace the string to
else
, but it stays assomething
. As a result, this testcase fails. I'm on the latest version offx
(v1.22.1).However, this passes:
Expected behavior
I expect that the decorate inside the module still runs, and we populate the type after the decorate executes. The testcase above should pass.
Additional context
I believe this is because
fx.Populate
runs as anfx.Invoke
, which runs at the top level scope and doesn't look at decorators in the child scope.The text was updated successfully, but these errors were encountered: