/
condition.go
72 lines (59 loc) · 1.88 KB
/
condition.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
package container
import (
"errors"
"reflect"
)
type Conditional interface {
getInitFunc() interface{}
getOnCondition() interface{}
matched(cc Container) (bool, error)
}
type conditional struct {
init interface{}
on interface{}
}
// WithCondition 创建 Conditional 接口实例
// init 参数为传递个 Singleton/Prototype 方法的实例创建方法
// onCondition 参数支持两种形式
// - `onCondition(依赖注入参数列表...) bool`
// - `onCondition(依赖注入参数列表...) (bool, error)`
func WithCondition(init interface{}, onCondition interface{}) Conditional {
if onCondition == nil {
panic("invalid argument onCondition: can not be nil [onCondition() bool or onCondition() (bool, error)]")
}
onType := reflect.TypeOf(onCondition)
if onType.Kind() != reflect.Func {
panic("invalid argument onCondition: must be a func [onCondition() bool or onCondition() (bool, error)]")
}
argCount := onType.NumOut()
if argCount != 1 && argCount != 2 {
panic("invalid argument onCondition: onCondition() bool or onCondition() (bool, error)")
}
if onType.Out(0).Kind() != reflect.Bool {
panic("invalid argument onCondition: return value must be bool [onCondition() bool or onCondition() (bool, error)]")
}
// onCondition() (bool, error)
if argCount == 2 {
if onType.Out(1) != reflect.TypeOf(errors.New("")) {
panic("invalid argument onCondition: the second return value must be error [onCondition() (bool, error)]")
}
}
return conditional{init: init, on: onCondition}
}
func (cond conditional) getInitFunc() interface{} {
return cond.init
}
func (cond conditional) getOnCondition() interface{} {
return cond.on
}
func (cond conditional) matched(cc Container) (bool, error) {
res, err := cc.Call(cond.on)
if err != nil {
return false, err
}
if len(res) == 2 {
matched, err := res[0], res[1]
return matched.(bool), err.(error)
}
return res[0].(bool), nil
}