-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocator.go
81 lines (68 loc) · 1.21 KB
/
locator.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
package locator
import (
"fmt"
"sync"
)
var (
instance *locator
once sync.Once
)
type locator struct {
m sync.RWMutex
services map[string]any
}
func (l *locator) register(t any, s any) {
name := l.getTypeName(t)
l.m.Lock()
l.services[name] = s
l.m.Unlock()
}
func (l *locator) resolve(t any) (any, error) {
name := l.getTypeName(t)
l.m.RLock()
s, ok := l.services[name]
l.m.RUnlock()
if !ok {
return nil, fmt.Errorf("service not found: %T", t)
}
return s, nil
}
func (l *locator) getTypeName(myvar any) string {
return fmt.Sprintf("%T", myvar)
}
func (l *locator) list() []interface{} {
l.m.RLock()
defer l.m.RUnlock()
var list []interface{}
for _, v := range l.services {
list = append(list, v)
}
return list
}
func newServiceLocator() *locator {
once.Do(func() {
instance = &locator{
m: sync.RWMutex{},
services: map[string]interface{}{},
}
})
return instance
}
func Register[T any](s T) {
l := newServiceLocator()
var t T
l.register(&t, s)
}
func Resolve[T any]() (T, error) {
l := newServiceLocator()
var t T
obj, err := l.resolve(&t)
if err != nil {
return t, err
}
return obj.(T), err
}
func List() []any {
l := newServiceLocator()
return l.list()
}