There are Go packages that help with dependency injection, employing
reflection.
And other practices insist on passing everything as an argument, down the
pipe; employing mostly factory methods.
At the same time putting long-lived instances inside a context is not
recommended - I like context for cancellation (and hierarchy of
cancellations) and I like it for passing state when every step in a
pipeline is concurrent and short lived; for other uses, using context seems
a not proper choice.
Struggling with these thoughts, something like a hierarchical service
locator came to my mind:
type DepRegistry struct {
parent *DepRegistry
deps sync.Map
}
func (r *DepRegistry) Register(name string, dep interface{}) {
r.deps.Store(name, dep)
}
// Load first loads from current instance, then tries
// to load from parent (panics if fails to find)
func (r *DepRegistry) Load(name string) interface{} {
dep, ok := r.deps.Load(name)
if !ok {
if r.parent != nil {
return r.parent.Load(name)
}
panic("unknown dep " + name)
}
return dep
}
func NewDepRegistry(parent ...*DepRegistry) *DepRegistry {
res := &DepRegistry{}
if len(parent) > 0 && parent[0] != nil {
res.parent = parent[0]
}
return res
}
I would love to hear thoughts on this matter. Is it an acceptable solution?
Is there anything missing?
Sample App: There is this app, with different packages that are using
services like logging, creating/modifying images, sending/receiving
messages from bots and the like. Those parts are already separate
executables, communication via NATS.
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.