-
Notifications
You must be signed in to change notification settings - Fork 1
/
value-interceptor-factory.go
93 lines (80 loc) · 2.58 KB
/
value-interceptor-factory.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
package valuesvc
import (
"reflect"
"sync"
"github.com/ahl5esoft/lite-go/contract"
mcontract "github.com/ahl5esoft/lite-go/model/contract"
"github.com/ahl5esoft/lite-go/model/message"
"github.com/ahl5esoft/lite-go/service/iocsvc"
)
type predicateInterceptor struct {
interceptor contract.IValueInterceptor
predicate func(mcontract.IEnumItem) bool
}
// 数值拦截器工厂
type valueInterceptorFactory[T mcontract.IEnumItem] struct {
defaultInterceptor contract.IValueInterceptor
enumFacotry contract.IEnumFactory
once sync.Once
metadata map[int]reflect.Type
predicateInterceptors []predicateInterceptor
valueTypeInterceptor map[int]contract.IValueInterceptor
}
func (m *valueInterceptorFactory[T]) Build(changeValue message.ChangeValue) (res contract.IValueInterceptor, err error) {
m.once.Do(func() {
var enumService contract.IEnumService[T]
if err = m.enumFacotry.Build("ValueType", &enumService); err != nil {
return
}
var valueTypeItems []T
if valueTypeItems, err = enumService.AllItems(); err != nil {
return
}
for _, r := range valueTypeItems {
if v, ok := m.valueTypeInterceptor[r.GetValue()]; ok {
t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
m.metadata[r.GetValue()] = t
} else {
for _, cr := range m.predicateInterceptors {
if cr.predicate(r) {
m.metadata[r.GetValue()] = reflect.TypeOf(cr.interceptor)
break
}
}
}
}
})
if err != nil {
return
}
if t, ok := m.metadata[changeValue.ValueType]; ok {
v := reflect.New(t)
iocsvc.Inject(v, nil)
res = v.Interface().(contract.IValueInterceptor)
} else {
res = m.defaultInterceptor
}
return
}
func (m *valueInterceptorFactory[T]) Register(valueType int, interceptor contract.IValueInterceptor) {
m.valueTypeInterceptor[valueType] = interceptor
}
func (m *valueInterceptorFactory[T]) RegisterPredicate(predicate func(mcontract.IEnumItem) bool, interceptor contract.IValueInterceptor) {
m.predicateInterceptors = append(m.predicateInterceptors, predicateInterceptor{
interceptor: interceptor,
predicate: predicate,
})
}
// 创建枚举拦截器工厂
func NewValueInterceptorFactory[T mcontract.IEnumItem](enumFacotry contract.IEnumFactory) contract.IValueInterceptorFactory {
return &valueInterceptorFactory[T]{
defaultInterceptor: new(emptyValueInterceptor),
enumFacotry: enumFacotry,
metadata: make(map[int]reflect.Type),
predicateInterceptors: make([]predicateInterceptor, 0),
valueTypeInterceptor: make(map[int]contract.IValueInterceptor),
}
}