Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions container_keyed_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ import (
)

// GetKeyedFromContainer Retrieves an instance from the given container based on type and key (panics if no valid implementations)
func GetKeyedFromContainer[T any](con *Container, ctx context.Context, key KeyStringer) (T, context.Context) {
if key == nil {
panic(nilKey)
}
func GetKeyedFromContainer[T any, K comparable](con *Container, ctx context.Context, key K) (T, context.Context) {
return getFromContainer[T](con, ctx, key)
}

// GetKeyedListFromContainer Retrieves a list of instances from the given container based on type and key
func GetKeyedListFromContainer[T any](con *Container, ctx context.Context, key KeyStringer) ([]T, context.Context) {
if key == nil {
panic(nilKey)
}
func GetKeyedListFromContainer[T any, K comparable](con *Container, ctx context.Context, key K) ([]T, context.Context) {
return getListFromContainer[T](con, ctx, key)
}
25 changes: 5 additions & 20 deletions container_keyed_registerers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,32 @@ import (
)

// RegisterKeyedCreatorToContainer Registers a lazily initialized value to the given container using a `Creator[T]` interface
func RegisterKeyedCreatorToContainer[T any](con *Container, lifetime Lifetime, creator Creator[T], key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedCreatorToContainer[T any, K comparable](con *Container, lifetime Lifetime, creator Creator[T], key K) {
registerCreatorToContainer(con, lifetime, creator, key)
}

// RegisterKeyedSingletonToContainer Registers an eagerly instantiated singleton value to the given container.
// To register an eagerly instantiated scoped value use [ProvideScopedValueToContainer]
func RegisterKeyedSingletonToContainer[T any](con *Container, impl T, key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedSingletonToContainer[T any, K comparable](con *Container, impl T, key K) {
registerSingletonToContainer(con, impl, key)
}

// RegisterKeyedFuncToContainer Registers a lazily initialized value to the given container using an `Initializer[T]` function signature
func RegisterKeyedFuncToContainer[T any](con *Container, lifetime Lifetime, initializer Initializer[T], key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedFuncToContainer[T any, K comparable](con *Container, lifetime Lifetime, initializer Initializer[T], key K) {
registerFuncToContainer(con, lifetime, initializer, key)
}

// RegisterKeyedPlaceholderToContainer registers a future value with Scoped lifetime to the given container.
// This value will be injected in runtime using the [ProvideScopedValue] function.
// Resolving objects which depend on this value will panic if the value has not been provided.
// Placeholder with the same type and key can be registered only once.
func RegisterKeyedPlaceholderToContainer[T any](con *Container, key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedPlaceholderToContainer[T any, K comparable](con *Container, key K) {
registerPlaceholderToContainer[T](con, key)
}

// ProvideKeyedScopedValueToContainer injects a concrete value into the given context.
// This value will be available only to the given container. And the container can only resolve this value if
// it has the matching (type and key's) Placeholder registered. Checkout the [RegisterPlaceholderToContainer] function for more info.
func ProvideKeyedScopedValueToContainer[T any](con *Container, ctx context.Context, value T, key KeyStringer) context.Context {
if key == nil {
panic(nilKey)
}
func ProvideKeyedScopedValueToContainer[T any, K comparable](con *Container, ctx context.Context, value T, key K) context.Context {
return provideScopedValueToContainer(con, ctx, value, key)
}
4 changes: 2 additions & 2 deletions container_unkeyed_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (

// GetFromContainer Retrieves an instance from the given container based on type and key (panics if no valid implementations)
func GetFromContainer[T any](con *Container, ctx context.Context) (T, context.Context) {
return getFromContainer[T](con, ctx, nil)
return getFromContainer[T](con, ctx, nilKey)
}

// GetListFromContainer Retrieves a list of instances from the given container based on type and key
func GetListFromContainer[T any](con *Container, ctx context.Context) ([]T, context.Context) {
return getListFromContainer[T](con, ctx, nil)
return getListFromContainer[T](con, ctx, nilKey)
}
10 changes: 5 additions & 5 deletions container_unkeyed_registerers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ import (

// RegisterCreatorToContainer Registers a lazily initialized value to the given container using a `Creator[T]` interface
func RegisterCreatorToContainer[T any](con *Container, lifetime Lifetime, creator Creator[T]) {
registerCreatorToContainer(con, lifetime, creator, nil)
registerCreatorToContainer(con, lifetime, creator, nilKey)
}

// RegisterSingletonToContainer Registers an eagerly instantiated singleton value to the given container.
// To register an eagerly instantiated scoped value use [ProvideScopedValueToContainer]
func RegisterSingletonToContainer[T any](con *Container, impl T) {
registerSingletonToContainer(con, impl, nil)
registerSingletonToContainer(con, impl, nilKey)
}

// RegisterFuncToContainer Registers a lazily initialized value to the given container using an `Initializer[T]` function signature
func RegisterFuncToContainer[T any](con *Container, lifetime Lifetime, initializer Initializer[T]) {
registerFuncToContainer(con, lifetime, initializer, nil)
registerFuncToContainer(con, lifetime, initializer, nilKey)
}

// RegisterPlaceholderToContainer registers a future value with Scoped lifetime to the given container.
// This value will be injected in runtime using the [ProvideScopedValue] function.
// Resolving objects which depend on this value will panic if the value has not been provided.
// Placeholder with the same type and key can be registered only once.
func RegisterPlaceholderToContainer[T any](con *Container) {
registerPlaceholderToContainer[T](con, nil)
registerPlaceholderToContainer[T](con, nilKey)
}

// ProvideScopedValueToContainer injects a concrete value into the given context.
// This value will be available only to the given container. And the container can only resolve this value if
// it has the matching (type and key's) Placeholder registered. Checkout the [RegisterPlaceholderToContainer] function for more info.
func ProvideScopedValueToContainer[T any](con *Container, ctx context.Context, value T) context.Context {
return provideScopedValueToContainer(con, ctx, value, nil)
return provideScopedValueToContainer(con, ctx, value, nilKey)
}
18 changes: 2 additions & 16 deletions creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package ore

import (
"context"
"testing"

"github.com/firasdarwish/ore/internal/interfaces"
"github.com/firasdarwish/ore/internal/models"
"testing"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -161,21 +162,6 @@ func TestRegisterCreatorTransientState(t *testing.T) {
}
}

func TestRegisterCreatorNilKeyOnRegistering(t *testing.T) {
clearAll()
assert.Panics(t, func() {
RegisterKeyedCreator[interfaces.SomeCounter](Scoped, &models.SimpleCounter{}, nil)
})
}

func TestRegisterCreatorNilKeyOnGetting(t *testing.T) {
clearAll()
RegisterKeyedCreator[interfaces.SomeCounter](Scoped, &models.SimpleCounter{}, "firas")
assert.Panics(t, func() {
GetKeyed[interfaces.SomeCounter](context.Background(), nil)
})
}

func TestRegisterCreatorGeneric(t *testing.T) {
for _, registrationType := range types {
clearAll()
Expand Down
10 changes: 2 additions & 8 deletions default_container_keyed_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ import (
)

// GetKeyed Retrieves an instance based on type and key (panics if no valid implementations)
func GetKeyed[T any](ctx context.Context, key KeyStringer) (T, context.Context) {
if key == nil {
panic(nilKey)
}
func GetKeyed[T any, K comparable](ctx context.Context, key K) (T, context.Context) {
return getFromContainer[T](DefaultContainer, ctx, key)
}

// GetKeyedList Retrieves a list of instances based on type and key
func GetKeyedList[T any](ctx context.Context, key KeyStringer) ([]T, context.Context) {
if key == nil {
panic(nilKey)
}
func GetKeyedList[T any, K comparable](ctx context.Context, key K) ([]T, context.Context) {
return getListFromContainer[T](DefaultContainer, ctx, key)
}
25 changes: 5 additions & 20 deletions default_container_keyed_registerers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,32 @@ package ore
import "context"

// RegisterKeyedCreator Registers a lazily initialized value using a `Creator[T]` interface
func RegisterKeyedCreator[T any](lifetime Lifetime, creator Creator[T], key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedCreator[T any, K comparable](lifetime Lifetime, creator Creator[T], key K) {
registerCreatorToContainer[T](DefaultContainer, lifetime, creator, key)
}

// RegisterKeyedSingleton Registers an eagerly instantiated singleton value
// To register an eagerly instantiated scoped value use [ProvideScopedValue]
func RegisterKeyedSingleton[T any](impl T, key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedSingleton[T any, K comparable](impl T, key K) {
registerSingletonToContainer[T](DefaultContainer, impl, key)
}

// RegisterKeyedFunc Registers a lazily initialized value using an `Initializer[T]` function signature
func RegisterKeyedFunc[T any](lifetime Lifetime, initializer Initializer[T], key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedFunc[T any, K comparable](lifetime Lifetime, initializer Initializer[T], key K) {
registerFuncToContainer(DefaultContainer, lifetime, initializer, key)
}

// RegisterKeyedPlaceholder registers a future value with Scoped lifetime.
// This value will be injected in runtime using the [ProvideScopedValue] function.
// Resolving objects which depend on this value will panic if the value has not been provided.
// Placeholder with the same type and key can be registered only once.
func RegisterKeyedPlaceholder[T any](key KeyStringer) {
if key == nil {
panic(nilKey)
}
func RegisterKeyedPlaceholder[T any, K comparable](key K) {
registerPlaceholderToContainer[T](DefaultContainer, key)
}

// ProvideKeyedScopedValue injects a concrete value into the given context.
// This value will be available only to the default container. And the container can only resolve this value if
// it has the matching (type and key's) Placeholder registered. Checkout the [RegisterPlaceholder] function for more info.
func ProvideKeyedScopedValue[T any](ctx context.Context, value T, key KeyStringer) context.Context {
if key == nil {
panic(nilKey)
}
func ProvideKeyedScopedValue[T any, K comparable](ctx context.Context, value T, key K) context.Context {
return provideScopedValueToContainer(DefaultContainer, ctx, value, key)
}
4 changes: 2 additions & 2 deletions default_container_unkeyed_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (

// Get Retrieves an instance based on type and key (panics if no valid implementations)
func Get[T any](ctx context.Context) (T, context.Context) {
return getFromContainer[T](DefaultContainer, ctx, nil)
return getFromContainer[T](DefaultContainer, ctx, nilKey)
}

// GetList Retrieves a list of instances based on type and key
func GetList[T any](ctx context.Context) ([]T, context.Context) {
return getListFromContainer[T](DefaultContainer, ctx, nil)
return getListFromContainer[T](DefaultContainer, ctx, nilKey)
}
10 changes: 5 additions & 5 deletions default_container_unkeyed_registerers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ import "context"

// RegisterCreator Registers a lazily initialized value using a `Creator[T]` interface
func RegisterCreator[T any](lifetime Lifetime, creator Creator[T]) {
registerCreatorToContainer[T](DefaultContainer, lifetime, creator, nil)
registerCreatorToContainer[T](DefaultContainer, lifetime, creator, nilKey)
}

// RegisterSingleton Registers an eagerly instantiated singleton value
// To register an eagerly instantiated scoped value use [ProvideScopedValue]
func RegisterSingleton[T any](impl T) {
registerSingletonToContainer[T](DefaultContainer, impl, nil)
registerSingletonToContainer[T](DefaultContainer, impl, nilKey)
}

// RegisterFunc Registers a lazily initialized value using an `Initializer[T]` function signature
func RegisterFunc[T any](lifetime Lifetime, initializer Initializer[T]) {
registerFuncToContainer(DefaultContainer, lifetime, initializer, nil)
registerFuncToContainer(DefaultContainer, lifetime, initializer, nilKey)
}

// RegisterPlaceholder registers a future value with Scoped lifetime.
// This value will be injected in runtime using the [ProvideScopedValue] function.
// Resolving objects which depend on this value will panic if the value has not been provided.
// Placeholder with the same type and key can be registered only once.
func RegisterPlaceholder[T any]() {
registerPlaceholderToContainer[T](DefaultContainer, nil)
registerPlaceholderToContainer[T](DefaultContainer, nilKey)
}

// ProvideScopedValue injects a concrete value into the given context.
// This value will be available only to the default container. And the container can only resolve this value if
// it has the matching (type and key's) Placeholder registered. Checkout the [RegisterPlaceholder] function for more info.
func ProvideScopedValue[T any](ctx context.Context, value T) context.Context {
return provideScopedValueToContainer(DefaultContainer, ctx, value, nil)
return provideScopedValueToContainer(DefaultContainer, ctx, value, nilKey)
}
18 changes: 2 additions & 16 deletions eager_singleton_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package ore

import (
"context"
"testing"

"github.com/firasdarwish/ore/internal/interfaces"
"github.com/firasdarwish/ore/internal/models"
"testing"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -88,21 +89,6 @@ func TestRegisterSingletonSingletonState(t *testing.T) {
}
}

func TestRegisterSingletonNilKeyOnRegistering(t *testing.T) {
clearAll()
assert.Panics(t, func() {
RegisterKeyedSingleton[interfaces.SomeCounter](&models.SimpleCounter{}, nil)
})
}

func TestRegisterSingletonNilKeyOnGetting(t *testing.T) {
clearAll()
RegisterKeyedSingleton[interfaces.SomeCounter](&models.SimpleCounter{}, "firas")
assert.Panics(t, func() {
GetKeyed[interfaces.SomeCounter](context.Background(), nil)
})
}

func TestRegisterSingletonGeneric(t *testing.T) {
clearAll()

Expand Down
1 change: 0 additions & 1 deletion errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,3 @@ func typeAlreadyRegistered(typeID typeID) error {

var alreadyBuilt = errors.New("services container is already sealed")
var alreadyBuiltCannotAdd = errors.New("cannot register new resolvers, container is sealed")
var nilKey = errors.New("cannot use nil key")
12 changes: 2 additions & 10 deletions initializer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package ore

import (
"context"
"testing"

"github.com/firasdarwish/ore/internal/interfaces"
"github.com/firasdarwish/ore/internal/models"
"testing"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -272,15 +273,6 @@ func TestRegisterFuncTransientState(t *testing.T) {
}
}

func TestRegisterFuncNilKeyOnRegistering(t *testing.T) {
clearAll()
assert.Panics(t, func() {
RegisterKeyedFunc[interfaces.SomeCounter](Scoped, func(ctx context.Context) (interfaces.SomeCounter, context.Context) {
return &models.SimpleCounter{}, ctx
}, nil)
})
}

func TestRegisterFuncNilKeyOnGetting(t *testing.T) {
clearAll()
RegisterKeyedFunc[interfaces.SomeCounter](Scoped, func(ctx context.Context) (interfaces.SomeCounter, context.Context) {
Expand Down
4 changes: 2 additions & 2 deletions internal_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func sortAndSelect[TInterface any](list []*concrete) []TInterface {
return result
}

func getFromContainer[T any](con *Container, ctx context.Context, key KeyStringer) (T, context.Context) {
func getFromContainer[T any, K comparable](con *Container, ctx context.Context, key K) (T, context.Context) {
pointerTypeName := getPointerTypeName[T]()
typeID := getTypeID(pointerTypeName, key)
lastRegisteredResolver := con.getLastRegisteredResolver(typeID)
Expand Down Expand Up @@ -76,7 +76,7 @@ func getFromContainer[T any](con *Container, ctx context.Context, key KeyStringe
return concrete.value.(T), ctx
}

func getListFromContainer[T any](con *Container, ctx context.Context, key KeyStringer) ([]T, context.Context) {
func getListFromContainer[T any, K comparable](con *Container, ctx context.Context, key K) ([]T, context.Context) {
inputPointerTypeName := getPointerTypeName[T]()

con.lock.RLock()
Expand Down
Loading