-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathserviceinjector.go
54 lines (47 loc) · 1.33 KB
/
serviceinjector.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
package river
import "reflect"
type serviceInjector map[reflect.Type]interface{}
// Register registers a new service. Services are identifiable by their types.
// Multiple services of same type should be grouped into a struct,
// and the struct should be registered instead.
func (s *serviceInjector) Register(service interface{}) {
// don't allow context override
if reflect.TypeOf(service) == reflect.TypeOf(&Context{}) {
return
}
s.register(service)
}
func (s *serviceInjector) register(service interface{}) {
if *s == nil {
*s = make(serviceInjector)
}
(*s)[reflect.TypeOf(service)] = service
}
// invoke invokes function f. f must be Func type.
func (s serviceInjector) invoke(f interface{}) {
if reflect.TypeOf(f).Kind() != reflect.Func {
// log and return to prevent panic.
log.println("Cannot invoke non function type")
return
}
args := make([]reflect.Value, reflect.TypeOf(f).NumIn())
for i := range args {
argType := reflect.TypeOf(f).In(i)
if service, ok := s[argType]; ok {
args[i] = reflect.ValueOf(service)
} else {
// set zero value
args[i] = reflect.Zero(argType)
}
}
reflect.ValueOf(f).Call(args)
}
func copyInjectors(injectors ...serviceInjector) serviceInjector {
var s = serviceInjector{}
for i := range injectors {
for j := range injectors[i] {
s[j] = injectors[i][j]
}
}
return s
}