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

Private supplies #1206

Closed
saturn4er opened this issue May 27, 2024 · 1 comment
Closed

Private supplies #1206

saturn4er opened this issue May 27, 2024 · 1 comment

Comments

@saturn4er
Copy link

saturn4er commented May 27, 2024

Is your feature request related to a problem? Please describe.
fx.Private doesn't work with fx.Supply. It just supplies value of option to DI container. It would be nice to be able to use fx.Private in fx.Supply function as it now works with fx.Provide function

Is this a breaking change?
No, it's not

Simple code to check that fx.Supply doesn't work with fx.Private
Used fx version: v1.21.1

package main

import (
	"go.uber.org/fx"
)

func main() {
	fx.New(
		fx.Module(
			"tst",
			fx.Supply(1, fx.Private),
			fx.Supply("1", fx.Private),
		),
	)
}

output
cannot provide fx.privateOption from [0]: already provided by "reflect".makeFuncStub

JacobOaks added a commit to JacobOaks/fx that referenced this issue May 29, 2024
`fx.Supply` is essentially an API that allows for conveniently
`fx.Provide`ing an exact value, rather than a function that will return that value.

(ex: the following are equivalent):
```
fx.Provide(func() int { return 5 })
fx.Supply(5)
```

`fx.Private` allows for usage of a provided constructor's results
to be restricted to the current module and its child modules.

```
fx.Module(
	"parent",
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Provide(func() int { return 5 }, fx.Private),
	),
),
```

This PR allows for using `fx.Private` with `fx.Supply` as well,
so that folks can enjoy the convenience of `fx.Supply` when they also wish to
restrict the usage of the supplied value.

```
fx.Module(
	"parent"
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Supply(5, fx.Private),
	),
),
```

Ref uber-go#1206

Since the behavior between Supply + Private and Provide + Private
should be identical, I opted to generalize the existing `fx.Private` tests
to run for both Provide and Supply. This keeps the tests a little more DRY
but does complicate them/hurt readability. I feel like this is OK since
there are a lot of tests, but I also am the one who wrote the tests,
so I am biased regarding its readability.
I am happy to break out Supply + Private into its own tests
if folks think these tests are getting cluttered.
JacobOaks added a commit to JacobOaks/fx that referenced this issue May 29, 2024
`fx.Supply` is essentially an API that allows for conveniently
`fx.Provide`ing an exact value, rather than a function that will return that value.
For example, `fx.Provide(func() int { return 5 })` is equivalent to `fx.Supply(5)`.

`fx.Private` allows for usage of a provided constructor's results
to be restricted to the current module and its child modules.
```go
fx.Module(
	"parent",
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Provide(func() int { return 5 }, fx.Private),
	),
),
```

This PR allows for using `fx.Private` with `fx.Supply` as well,
so that folks can enjoy the convenience of `fx.Supply` when they also wish to
restrict the usage of the supplied value.
```go
fx.Module(
	"parent"
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Supply(5, fx.Private),
	),
),
```

Ref uber-go#1206

Since the behavior between Supply + Private and Provide + Private
should be identical, I opted to generalize the existing `fx.Private` tests
to run for both Provide and Supply. This keeps the tests a little more DRY
but does complicate them/hurt readability. I feel like this is OK since
there are a lot of tests, but I also am the one who wrote the tests,
so I am biased regarding its readability.
I am happy to break out Supply + Private into its own tests
if folks think these tests are getting cluttered.
JacobOaks added a commit to JacobOaks/fx that referenced this issue May 29, 2024
`fx.Supply` is essentially an API that allows for conveniently
`fx.Provide`ing an exact value, rather than a function that will return that value.
For example, `fx.Provide(func() int { return 5 })` is equivalent to `fx.Supply(5)`.

`fx.Private` allows for usage of a provided constructor's results
to be restricted to the current module and its child modules.
```go
fx.Module(
	"parent",
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Provide(func() int { return 5 }, fx.Private),
	),
),
```

This PR allows for using `fx.Private` with `fx.Supply` as well,
so that folks can enjoy the convenience of `fx.Supply` when they also wish to
restrict the usage of the supplied value.
```go
fx.Module(
	"parent"
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Supply(5, fx.Private),
	),
),
```

Ref uber-go#1206

Since the behavior between Supply + Private and Provide + Private
should be identical, I opted to generalize the existing `fx.Private` tests
to run for both Provide and Supply. This keeps the tests a little more DRY
but does complicate them/hurt readability. I feel like this is OK since
there are a lot of tests, but I also am the one who wrote the tests,
so I am biased regarding its readability.
I am happy to break out Supply + Private into its own tests
if folks think these tests are getting cluttered.
JacobOaks added a commit that referenced this issue May 30, 2024
`fx.Supply` is essentially an API that allows for conveniently
`fx.Provide`ing an exact value, rather than a function that will return
that value. For example, `fx.Provide(func() int { return 5 })` is
equivalent to `fx.Supply(5)`.

`fx.Private` allows for usage of a provided constructor's results to be
restricted to the current module and its child modules.
```go
fx.Module(
	"parent",
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Provide(func() int { return 5 }, fx.Private),
	),
),
```

This PR allows for using `fx.Private` with `fx.Supply` as well, so that
folks can enjoy the convenience of `fx.Supply` when they also wish to
restrict the usage of the supplied value.
```go
fx.Module(
	"parent"
	fx.Invoke(func(int) { /* this will error out! */ }),
	fx.Module(
		"child",
		fx.Supply(5, fx.Private),
	),
),
```

Ref #1206

Since the behavior between Supply + Private and Provide + Private should
be identical, I opted to generalize the existing `fx.Private` tests to
run for both Provide and Supply. This keeps the tests a little more DRY
but does complicate them/hurt readability. I feel like this is OK since
there are a lot of tests, but I also am the one who wrote the tests, so
I am biased regarding its readability. Thus, I am happy to break out
Supply + Private into its own tests if folks feel strongly that these
tests are hard to read.
@JacobOaks
Copy link
Contributor

Hey @saturn4er! This should be supported now with #1207 being merged. Will try to do a release today.

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

No branches or pull requests

2 participants