-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefinition.go
94 lines (79 loc) · 1.77 KB
/
definition.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
package di
import (
"github.com/rushstart/tid"
"reflect"
)
type DefinitionOption func(definitionOptions) definitionOptions
type definitionOptions struct {
scope scope
tag string
asValue bool
}
func WithScope(scope scope) DefinitionOption {
return func(opts definitionOptions) definitionOptions {
opts.scope = scope
return opts
}
}
func WithTag(t string) DefinitionOption {
return func(opts definitionOptions) definitionOptions {
opts.tag = t
return opts
}
}
type Definition struct {
id tid.ID
provider reflect.Value
asValue bool
ctor InvokeInfo
scope scope
order int
sign int64
}
func (d Definition) ValidateBinding(s Scope) error {
if d.sign != s.sign() {
return ErrInvalidDefinitionBinding
}
return nil
}
func (d Definition) resolve(s Scope) (instance, error) {
err := d.ValidateBinding(s)
if err != nil {
return instance{}, err
}
if d.asValue {
return instance{
value: d.provider,
cleanup: nil,
isset: true,
}, nil
}
out, err := d.ctor.Call(s)
if err != nil {
return instance{}, err
}
return newInstance(out)
}
func Define[T any](constructor any, opts ...DefinitionOption) Definition {
var options definitionOptions
for _, opt := range opts {
options = opt(options)
}
return define(tid.From[T](options.tag), reflect.ValueOf(constructor), options)
}
func DefineValue[T any](value T, opts ...DefinitionOption) Definition {
var options definitionOptions
for _, opt := range opts {
options = opt(options)
}
options.asValue = true
return define(tid.From[T](options.tag), reflect.ValueOf(value), options)
}
func define(id tid.ID, provider reflect.Value, opts definitionOptions) Definition {
return Definition{
id: id,
provider: provider,
scope: opts.scope,
asValue: opts.asValue,
}
}