Documentation
¶
Overview ¶
Package plumbing defines generic types for the dependency injection mechanisms in rig.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Factory ¶
Factory is a function that takes a parameter of type R and returns a value of type T along with a boolean reporting whether it could handle R.
A Factory may be called concurrently with itself, for the same input as well as for different ones, so it must not depend on being called one at a time.
type LazyService ¶
LazyService is a generic lazy-initializer that calls a provider function once and memoizes the result.
func NewLazyService ¶
func NewLazyService[S any, T any](get func(S) (T, error), source S) *LazyService[S, T]
NewLazyService creates a new instance of LazyService with the given provider function.
func (*LazyService[S, T]) Get ¶
func (s *LazyService[S, T]) Get() (T, error)
Get retrieves the service value, initializing it if necessary.
type Provider ¶
Provider is a generic provider of values of type T that can be initialized with a value of type R.
func NewProvider ¶
NewProvider creates a new instance of Provider. The error is returned if no factory can produce a value of type T.
func (*Provider[R, T]) Get ¶
Get returns the value from the first factory that reports a match, in registration order with any RegisterFirst factories ahead of the rest. If none of them match, the error supplied at creation time is returned.
A lookup never reorders the factories, so the result for a given input does not depend on what was looked up before it.
func (*Provider[R, T]) GetAll ¶
GetAll returns the values from every factory that reports a match, in registration order with any RegisterFirst factories ahead of the rest. If none of them match, the error supplied at creation time is returned.
func (*Provider[R, T]) Register ¶
Register adds a new factory to the provider.
Factories are consulted in registration order and the first one to match wins, after any added with RegisterFirst.
Prefer factories that decide for themselves whether they apply to an input over relying on that order: a factory matching a superset of another's inputs should exclude the cases the more specific one handles, the way os.ResolveLinuxCompat stands down for any host os-release can identify. A registry a package exports stays open for registration, so it cannot know where a caller's factory will land, and a broad factory registered early otherwise keeps winning over a more specific one added later.
func (*Provider[R, T]) RegisterFirst ¶ added in v2.2.0
RegisterFirst adds a factory at the front of the list, ahead of every factory already registered and every factory registered afterwards with Register. Where it is called more than once the most recent call is the one consulted first, so the last caller to ask for precedence gets it.
It is for a caller that has to take precedence over a factory the registry already holds: one matching a superset of the inputs their own factory handles, where self-exclusion is not available to them because the factory that would have to stand down is not theirs to change. A package registering factories into its own registry should use Register and have them decide from the input whether they apply.
The result of a lookup may be memoized by the caller of Get, so register before the first lookup rather than after.
Example ¶
ExampleProvider_RegisterFirst shows a caller taking precedence over a factory the registry already holds. Registering their own would leave it behind the catch-all, which matches every input and is consulted first.
package main
import (
"errors"
"fmt"
"github.com/k0sproject/rig/v2/plumbing"
)
func main() {
registry := plumbing.NewProvider[string, string](errors.New("no factory available"))
// Already in the registry, standing in for one of rig's built-ins.
registry.Register(func(string) (string, bool) {
return "builtin", true
})
registry.RegisterFirst(func(input string) (string, bool) {
if input == "myhost" {
return "mine", true
}
return "", false
})
mine, err := registry.Get("myhost")
if err != nil {
fmt.Println(err)
return
}
other, err := registry.Get("otherhost")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(mine, other)
}
Output: mine builtin