-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcontext.go
104 lines (83 loc) · 2.31 KB
/
context.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
93
94
95
96
97
98
99
100
101
102
103
104
package di
import (
"context"
"fmt"
)
// Context describe DI context propagator capabilities
type Context interface {
SetContainer(Container) Context
Container() Container
SetResolver(Resolver) Context
Resolver() Resolver
Visualize() []string
Raw() context.Context
}
// Ctx returns context propagator
func Ctx(ctxt context.Context) Context {
return &ctx{
Context: ctxt,
}
}
type ctxKey string
const (
ctxKeyContainer ctxKey = "di.ctx.container"
ctxKeyResolver ctxKey = "di.ctx.resolver"
)
type ctx struct {
context.Context
}
// SetContainer puts container to a context
func (self *ctx) SetContainer(c Container) Context {
self.Context = context.WithValue(self.Context, ctxKeyContainer, c)
return self
}
// Container returns container from context or returns a global container
func (self *ctx) Container() Container {
if c, has := self.Context.Value(ctxKeyContainer).(Container); has {
return c
}
return globalContext.Container()
}
// SetResolver puts container to a context
func (self *ctx) SetResolver(r Resolver) Context {
self.Context = context.WithValue(self.Context, ctxKeyResolver, r)
return self
}
// Resolver returns a resolver instance either preset or against a Container() output
func (self *ctx) Resolver() Resolver {
if r, has := self.Context.Value(ctxKeyResolver).(Resolver); has {
return r.With(self.Context)
}
return NewResolver(self.Container())
}
func (self *ctx) Visualize() []string {
var out = make([]string, 0, 100)
var r, ok = self.Resolver().(*resolver)
if !ok {
return out
}
out = append(out, fmt.Sprintf("resolver has [%d] containers", len(r.containers)))
for i, c := range r.containers {
var cnt *container
if cnt, ok = c.(*container); !ok {
continue
}
out = append(out, fmt.Sprintf(" -> container [%d] has [%d] type binding(s)", i, len(cnt.bindings)))
for t, bindingList := range cnt.bindings {
out = append(out, fmt.Sprintf(" -> [%s] has [%d] binding(s)", t.String(), len(bindingList)))
for name, binding := range bindingList {
out = append(out, fmt.Sprintf(" • [%s] %s declared at [%s]", name, func() string {
if binding.factory != nil {
return "factory"
}
return "instance"
}(), binding.caller))
}
}
}
return out
}
// Raw returns raw context.Context
func (self *ctx) Raw() context.Context {
return self.Context
}