fx
fx copied to clipboard
Can `fx.Private` be scoped as a top-level `fx.Option` instead of a `var`
Is your feature request related to a problem? Please describe.
I'd like to be able to continue the scoping story started with fx.Private
but make it a top-level fx.Option
that can be applied outside of fx.Provide
.
The usual pattern is for fx.Provide
to already be set in legacy codebases; I would prefer not to go back and change old code by adding an fx.private
into it. Instead I feel it may be easier and safer to create a new fx.Module
around this to "privatize" the legacy module.
Describe the solution you'd like Suppose we have legacy code that looks like this that we wish not to touch
package etcdmanagerfx
// imports
var Module = fx.Provide(
// ... other dependencies
NewEtcdManager,
)
type EtcdManager struct {
etcdAddr string
}
func NewEtcdManager(/* ... */) *EtcdManager {
// ...
}
in my main method I'd like to be able to do something like this to have two etcd's (perhaps a global and a regional)
package main
// imports
func main() {
fx.New(
fx.Module("global etcd submodule",
// ... other dependencies
etcdmanagerfx.Module,
fx.Private, // <-- make all dependencies private to other modules outside this scope
),
fx.Module("regional etcd submodule",
// ... other dependencies
etcdmanagerfx.Module,
fx.Private, // <-- make all dependencies private to other modules outside this scope
),
)
}
Describe alternatives you've considered None
Is this a breaking change? No
Additional context None
How about fx.Private
is like fx.Options
but, like all the content can only be used inside the nearest parent fx.Module
?
package examplefx
var Module = fx.Module("examplefx",
fx.Private(
fx.Provide(...), // only usable inside examplefx.Module
fx.Supply(...), // only usable inside examplefx.Module
etcdmanagerfx.Module, // only usable inside examplefx.Module
), // end Private
fx.Provide(...), // exposed to consumers of examplefx.Module
fx.Supply(...), // exposed to consumers of examplefx.Module
fx.Module("innermodule",
fx.Provide(...), // exposed to consumers of innermodule and consumers of examplefx.Module
fx.Private(...), // only usable inside innermodule. Other parts of examplefx.Module can't use it.
), // end inner module
)
Yes that would work.
One issue here is the naming collision since there is already
var Private = privateOption{}
Perhaps this can be named as
fx.PrivateScope(...)