Comments (6)
It's this kind of PR (title, content) that drives people away from open source contributions.
Please consider the possibility that the author didn't deliberately lie. It would have been approximately 1000x friendlier and more useful to have said "hey, %T
actually does reflection under the hood" and, ideally, offer a PR to change either the docs or the implementation.
from do.
There actually is a trick you can use to avoid reflection on map/context keys and it's called 0-width generic structs.
type key[T any] struct{}
Instances of such structs compare unequal if their T differs, such that key[string]{} != key[int]{}
and, as far as I know, they still take up 0 bytes. These are perfectly fine to use as a context or a map key, provided map has interface key type. I use this trick in my event emitter package: https://github.com/btvoidx/mint.
I would like to implement it and open a PR, but these reflected names are used as part of package public api (see (*Injector).ListProvidedServices
and related), so getting rid of them as map keys would not get rid of reflection, as type names are needed anyways, so this issue would still stand.
from do.
Is there no way to use the full path to the package from go.mod
in the service name instead of just the package in which it is located?
If you try to make Provide services with the same name and package in different subpackages it won't work
p1/p.Service
p2/p.Service
from do.
I totally agree with @kentquirk.
If someone else gets curious about the details of how it's using reflection (like I was), there's the piece of code (from fmt
package)
https://cs.opensource.google/go/go/+/refs/tags/go1.20.1:src/fmt/print.go;drc=1a9893a969e0a73dc4f1e48ed40ccaf29ec238a6;l=698
from do.
@btvoidx: Please implement Injector
with type key[T any] struct{}
. I'm sure many people would be interested. Regarding changing the API: there is always the option to create github.com/samber/do@v2
.
Minimal/global/simplified version could look like this:
package do
import (
"errors"
)
type key[T any] struct{ name string }
type provider[T any] func() (T, error)
var services = make(map[any]any)
func ProvideNamed[T any](name string, p provider[T]) {
services[key[T]{name}] = p
}
func ProvideNamedValue[T any](name string, v T) {
services[key[T]{name}] = v
}
func InvokeNamed[T any](name string) (T, error) {
provider, ok := services[key[T]{name}].(provider[T])
if ok {
return provider()
}
value, ok := services[key[T]{name}].(T)
if ok {
return value, nil
}
return empty[T](), errors.New("not found")
}
func Provide[T any](p provider[T]) {
ProvideNamed[T]("", p)
}
func ProvideValue[T any](v T) {
ProvideNamedValue[T]("", v)
}
func Invoke[T any]() (T, error) {
return InvokeNamed[T]("")
}
func empty[T any]() (t T) {
return
}
from do.
I think it is rather dishonest to still claim in the README to not use reflection when it has been pointed out that it does in fact use it.
from do.
Related Issues (20)
- Anonymous Invocation HOT 9
- Possible use of closed services in main() on shutdown HOT 2
- Invoke multiple services satisfying the interface HOT 2
- Proposal: do.Shutdown returning shutdown time ? HOT 1
- Proposal: allow multiple implementation for the same interface and being able to return all them HOT 6
- Data race when invoking services after shutdown HOT 1
- Warm up the container HOT 1
- proposal: Add factory provide mode HOT 1
- How to pass structs as inputs for those services HOT 1
- Is there an equivalent to dig.As() ? HOT 1
- shutdown all services even on error HOT 3
- Data race: unsynchronized read of `Injector.services` in `serviceNotFound` HOT 3
- Create application templates
- Debug: Web UI for listing scopes, services and dependencies HOT 1
- Add support of Value Groups HOT 5
- Troubleshooting: flamegraph of service invocation HOT 1
- v2: Feature Request - expose a method for add lifecycle hook HOT 2
- How can I InvokeNamed T to any HOT 7
- V2 Feature Request: add lifecycle interface support HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from do.