Skip to content

Commit

Permalink
push getters info shared internal funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
Firas Darwish committed Nov 15, 2024
1 parent ca3ee4f commit 408a56f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 94 deletions.
95 changes: 4 additions & 91 deletions container_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,105 +6,18 @@ 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, key ...KeyStringer) (T, context.Context) {
pointerTypeName := getPointerTypeName[T]()
typeID := getTypeID(pointerTypeName, key...)
lastRegisteredResolver := con.getLastRegisteredResolver(typeID)
if lastRegisteredResolver == nil { //not found, T is an alias

con.lock.RLock()
implementations, implExists := con.aliases[pointerTypeName]
con.lock.RUnlock()

if !implExists {
panic(noValidImplementation[T]())
}
count := len(implementations)
if count == 0 {
panic(noValidImplementation[T]())
}
for i := count - 1; i >= 0; i-- {
impl := implementations[i]
typeID = getTypeID(impl, key...)
lastRegisteredResolver = con.getLastRegisteredResolver(typeID)
if lastRegisteredResolver != nil {
break
}
}
}
if lastRegisteredResolver == nil {
panic(noValidImplementation[T]())
}
concrete, ctx := lastRegisteredResolver.resolveService(con, ctx)
return concrete.value.(T), ctx
return getFromContainer[T](con, ctx, key...)
}

// GetListFromContainer Retrieves a list of instances from the given container based on type and key
func GetListFromContainer[T any](con *Container, ctx context.Context, key ...KeyStringer) ([]T, context.Context) {
inputPointerTypeName := getPointerTypeName[T]()

con.lock.RLock()
pointerTypeNames, implExists := con.aliases[inputPointerTypeName]
con.lock.RUnlock()

if implExists {
pointerTypeNames = append(pointerTypeNames, inputPointerTypeName)
} else {
pointerTypeNames = []pointerTypeName{inputPointerTypeName}
}

servicesArray := []T{}

for i := 0; i < len(pointerTypeNames); i++ {
pointerTypeName := pointerTypeNames[i]
// generate type identifier
typeID := getTypeID(pointerTypeName, key...)

// try to get service resolver from container
con.lock.RLock()
resolvers, resolverExists := con.resolvers[typeID]
con.lock.RUnlock()

if !resolverExists {
continue
}

for index := 0; index < len(resolvers); index++ {
resolver := resolvers[index]
if resolver.isPlaceHolder() && !resolver.isScopedValueResolved(ctx) {
//the resolver is a placeHolder and the placeHolder's value has not been provided
//don't panic, just skip (don't add anything to the list)
continue
}
con, newCtx := resolver.resolveService(con, ctx)
servicesArray = append(servicesArray, con.value.(T))
ctx = newCtx
}
}

return servicesArray, ctx
return getListFromContainer[T](con, ctx, key...)
}

// GetResolvedSingletonsFromContainer retrieves a list of Singleton instances that implement the [TInterface] from the given container.
// See [GetResolvedSingletons] for more information.
func GetResolvedSingletonsFromContainer[TInterface any](con *Container) []TInterface {
con.lock.RLock()
defer con.lock.RUnlock()

list := []*concrete{}

//filtering
for _, resolvers := range con.resolvers {
for _, resolver := range resolvers {
con, isInvokedSingleton := resolver.getInvokedSingleton()
if isInvokedSingleton {
if _, ok := con.value.(TInterface); ok {
list = append(list, con)
}
}
}
}

return sortAndSelect[TInterface](list)
return getResolvedSingletonsFromContainer[TInterface](con)
}

// TODO separate to a file
Expand All @@ -121,7 +34,7 @@ func GetResolvedSingletonsFromContainer[TInterface any](con *Container) []TInter
// disposable.Dispose()
// }
func GetResolvedSingletons[TInterface any]() []TInterface {
return GetResolvedSingletonsFromContainer[TInterface](DefaultContainer)
return getResolvedSingletonsFromContainer[TInterface](DefaultContainer)
}

// TODO separate to a file
Expand Down
4 changes: 2 additions & 2 deletions default_container_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, key ...KeyStringer) (T, context.Context) {
return GetFromContainer[T](DefaultContainer, ctx, key...)
return getFromContainer[T](DefaultContainer, ctx, key...)
}

// GetList Retrieves a list of instances based on type and key
func GetList[T any](ctx context.Context, key ...KeyStringer) ([]T, context.Context) {
return GetListFromContainer[T](DefaultContainer, ctx, key...)
return getListFromContainer[T](DefaultContainer, ctx, key...)
}
104 changes: 103 additions & 1 deletion internal_getters.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ore

import "sort"
import (
"context"
"sort"
)

func (this *Container) getLastRegisteredResolver(typeID typeID) serviceResolver {
// try to get service resolver from container
Expand Down Expand Up @@ -39,3 +42,102 @@ func sortAndSelect[TInterface any](list []*concrete) []TInterface {
}
return result
}

func getFromContainer[T any](con *Container, ctx context.Context, key ...KeyStringer) (T, context.Context) {
pointerTypeName := getPointerTypeName[T]()
typeID := getTypeID(pointerTypeName, key...)

Check failure on line 48 in internal_getters.go

View workflow job for this annotation

GitHub Actions / build

cannot use ... in call to non-variadic getTypeID
lastRegisteredResolver := con.getLastRegisteredResolver(typeID)
if lastRegisteredResolver == nil { //not found, T is an alias

con.lock.RLock()
implementations, implExists := con.aliases[pointerTypeName]
con.lock.RUnlock()

if !implExists {
panic(noValidImplementation[T]())
}
count := len(implementations)
if count == 0 {
panic(noValidImplementation[T]())
}
for i := count - 1; i >= 0; i-- {
impl := implementations[i]
typeID = getTypeID(impl, key...)

Check failure on line 65 in internal_getters.go

View workflow job for this annotation

GitHub Actions / build

cannot use ... in call to non-variadic getTypeID
lastRegisteredResolver = con.getLastRegisteredResolver(typeID)
if lastRegisteredResolver != nil {
break
}
}
}
if lastRegisteredResolver == nil {
panic(noValidImplementation[T]())
}
concrete, ctx := lastRegisteredResolver.resolveService(con, ctx)
return concrete.value.(T), ctx
}

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

con.lock.RLock()
pointerTypeNames, implExists := con.aliases[inputPointerTypeName]
con.lock.RUnlock()

if implExists {
pointerTypeNames = append(pointerTypeNames, inputPointerTypeName)
} else {
pointerTypeNames = []pointerTypeName{inputPointerTypeName}
}

servicesArray := []T{}

for i := 0; i < len(pointerTypeNames); i++ {
pointerTypeName := pointerTypeNames[i]
// generate type identifier
typeID := getTypeID(pointerTypeName, key...)

Check failure on line 97 in internal_getters.go

View workflow job for this annotation

GitHub Actions / build

cannot use ... in call to non-variadic getTypeID

// try to get service resolver from container
con.lock.RLock()
resolvers, resolverExists := con.resolvers[typeID]
con.lock.RUnlock()

if !resolverExists {
continue
}

for index := 0; index < len(resolvers); index++ {
resolver := resolvers[index]
if resolver.isPlaceHolder() && !resolver.isScopedValueResolved(ctx) {
//the resolver is a placeHolder and the placeHolder's value has not been provided
//don't panic, just skip (don't add anything to the list)
continue
}
con, newCtx := resolver.resolveService(con, ctx)
servicesArray = append(servicesArray, con.value.(T))
ctx = newCtx
}
}

return servicesArray, ctx
}

func getResolvedSingletonsFromContainer[TInterface any](con *Container) []TInterface {
con.lock.RLock()
defer con.lock.RUnlock()

list := []*concrete{}

//filtering
for _, resolvers := range con.resolvers {
for _, resolver := range resolvers {
con, isInvokedSingleton := resolver.getInvokedSingleton()
if isInvokedSingleton {
if _, ok := con.value.(TInterface); ok {
list = append(list, con)
}
}
}
}

return sortAndSelect[TInterface](list)
}

0 comments on commit 408a56f

Please sign in to comment.