Skip to content
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

Can fx.Private be scoped as a top-level fx.Option instead of a var #1020

Open
rossb83 opened this issue Jan 10, 2023 · 3 comments
Open

Can fx.Private be scoped as a top-level fx.Option instead of a var #1020

rossb83 opened this issue Jan 10, 2023 · 3 comments

Comments

@rossb83
Copy link
Contributor

rossb83 commented Jan 10, 2023

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

@jkanywhere
Copy link
Contributor

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
)

@rossb83
Copy link
Contributor Author

rossb83 commented Jan 14, 2023

Yes that would work.

@rossb83
Copy link
Contributor Author

rossb83 commented Jan 15, 2023

One issue here is the naming collision since there is already

var Private = privateOption{}

Perhaps this can be named as

fx.PrivateScope(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants