/
containerLineage.go
65 lines (51 loc) · 1.35 KB
/
containerLineage.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
package di
import (
"errors"
"fmt"
)
// containerLineage contains all the functions that are useful
// to retrieve or create the parent and children of a container.
type containerLineage struct{}
func (l *containerLineage) Parent(ctn *container) Container {
return l.parent(ctn)
}
func (l *containerLineage) parent(ctn *container) *container {
ctn.m.RLock()
parent := ctn.containerCore.parent
ctn.m.RUnlock()
return &container{
containerCore: parent,
}
}
func (l *containerLineage) SubContainer(ctn *container) (Container, error) {
child, err := l.createChild(ctn)
if err != nil {
return nil, err
}
ctn.m.Lock()
if ctn.closed {
ctn.m.Unlock()
return nil, errors.New("the container is closed")
}
ctn.children[child.containerCore] = struct{}{}
ctn.m.Unlock()
return child, nil
}
func (l *containerLineage) createChild(ctn *container) (*container, error) {
subscopes := ctn.SubScopes()
if len(subscopes) == 0 {
return nil, fmt.Errorf("there is no more specific scope than `%s`", ctn.scope)
}
return &container{
containerCore: &containerCore{
scope: subscopes[0],
scopes: ctn.scopes,
definitions: ctn.definitions,
parent: ctn.containerCore,
children: map[*containerCore]struct{}{},
unscopedChild: nil,
objects: map[objectKey]interface{}{},
dependencies: newGraph(),
},
}, nil
}