feat: Support singleton providers (#501)
* feat: Support singleton providers This change adds support for provider functions that are not reinvoked even if requested by multiple other providers. Instead, their value is cached and reused between invocations. To make this possible, we change how bindings are stored: instead of just a function reference, we now store a binding object which records whether the binding is a singleton, and records the resolved singleton value (if any). Resolves #500 * refac(bindings): hide singleton status Don't require callAnyFunction to be aware of whether a binding is a singleton or not.
This commit is contained in:
@@ -119,6 +119,43 @@ func TestBindToProvider(t *testing.T) {
|
||||
assert.True(t, cli.Called)
|
||||
}
|
||||
|
||||
func TestBindSingletonProvider(t *testing.T) {
|
||||
type (
|
||||
Connection struct{}
|
||||
ClientA struct{ conn *Connection }
|
||||
ClientB struct{ conn *Connection }
|
||||
)
|
||||
|
||||
var numConnections int
|
||||
newConnection := func() *Connection {
|
||||
numConnections++
|
||||
return &Connection{}
|
||||
}
|
||||
|
||||
var cli struct{}
|
||||
app, err := New(&cli,
|
||||
BindSingletonProvider(newConnection),
|
||||
BindToProvider(func(conn *Connection) *ClientA {
|
||||
return &ClientA{conn: conn}
|
||||
}),
|
||||
BindToProvider(func(conn *Connection) *ClientB {
|
||||
return &ClientB{conn: conn}
|
||||
}),
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ctx, err := app.Parse([]string{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = ctx.Call(func(a *ClientA, b *ClientB) {
|
||||
assert.NotZero(t, a.conn)
|
||||
assert.NotZero(t, b.conn)
|
||||
|
||||
assert.Equal(t, 1, numConnections, "expected newConnection to be called only once")
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestFlagNamer(t *testing.T) {
|
||||
var cli struct {
|
||||
SomeFlag string
|
||||
|
||||
Reference in New Issue
Block a user