-
Notifications
You must be signed in to change notification settings - Fork 0
/
container_helpers.go
92 lines (78 loc) · 2.88 KB
/
container_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package container
import (
"log"
"reflect"
"unsafe"
)
// hasBinding - Look up a Type in the container and return whether it exists
func (container *ContainerInstance) hasBinding(binding reflect.Type) bool {
_, ok := container.bindings[binding]
return ok
}
// getBindingType - Try to get a binding type from the binding arg in a few different ways
// We'll first assume we're checking for an abstract type binding...
// If we didn't get it from the abstract, we'll then check for the concrete...
// Now as a last ditch effort, we'll look the bindingType up in container.concretes
// If we can't find anything, we return nil
func (container *ContainerInstance) getBindingType(binding any) reflect.Type {
bindingType := getType(binding)
// First, we'll check if we have this type as a singleton binding
testType := getConcreteReturnType(bindingType)
if container.hasBinding(testType) {
return testType
}
// We'll first assume we're checking for an abstract type binding...
testType = getAbstractReturnType(bindingType)
if container.hasBinding(testType) {
return testType
}
// If we didn't get it from the abstract, we'll then check for the concrete...
testType = getConcreteReturnType(bindingType)
if container.hasBinding(testType) {
return testType
}
// Now as a last ditch effort, we'll look the bindingType up in container.concretes
if potentialAbstract, ok := container.concretes[bindingType]; ok {
if container.hasBinding(potentialAbstract) {
return potentialAbstract
}
}
// ... and one more final last ditch effort... check call this method on the parent container
if container.parent != nil {
if t := container.parent.getBindingType(bindingType); t != nil {
return t
}
}
return nil
}
// makeFromBinding - Once we've obtained our binding type from
// Make, we'll then check the containers bindings
// If it doesn't exist, and we have a parent container we'll then call makeFromBinding on the
// parent container. Which will either recurse until a resolve is made, or return nil
func (container *ContainerInstance) makeFromBinding(binding reflect.Type, parameters ...any) any {
containerBinding, ok := container.bindings[binding]
if !ok {
if container.parent != nil {
return container.parent.makeFromBinding(binding, parameters...)
}
log.Printf("Failed to resolve container binding for abstract type %s", binding.String())
return nil
}
return container.resolve(containerBinding, parameters...)
}
func (container *ContainerInstance) pointer() unsafe.Pointer {
return reflect.ValueOf(container).UnsafePointer()
}
func removeAllChildContainerInstances() {
// mainContainerPointer := Container.pointer()
//
// newContainerInstances := []unsafe.Pointer{}
//
// for _, containerPtr := range containerInstances {
// var container = *((*ContainerInstance)(containerPtr))
//
// if container.parent == nil && container.pointer() != mainContainerPointer {
//
// }
// }
}