-
Notifications
You must be signed in to change notification settings - Fork 0
/
factory_config.go
146 lines (136 loc) · 3.77 KB
/
factory_config.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package di
import (
"strings"
)
// FactoryConfig is the type to configure the component Factory.
// Container.Register accepts any number of config (this is functional option pattern).
type FactoryConfig func(*Factory)
// Singleton identifies a component that only instantiates once.
//
// Example:
//
// di.Register(func() MyService {
// return &MyServiceImpl{ Id: uuid.New() }
// }, di.Singleton)
//
// di.Register(func(s MyService) MyControllerA {
// print(s.Id) // uuid value
// })
//
// di.Register(func(s MyService) MyControllerB {
// print(s.Id) // same uuid value
// })
func Singleton(f *Factory) {
f.scope = SCOPE_SINGLETON
}
// Prototype identifies a component that a new instance is created
// every time the component factory is invoked.
//
// Example:
//
// di.Register(func() MyService {
// return &MyServiceImpl{ Id: uuid.New() }
// }, di.Prototype)
//
// di.Register(func(s MyService) MyControllerA {
// print(s.Id) // first uuid
// })
//
// di.Register(func(s MyService, ctn di.Container, ctx context.Context) MyControllerB {
// print(s.Id) // second uuid
//
// s2, _ := di.Get[testService](ctn, ctx)
// print(s2.Id) // third uuid
// })
func Prototype(f *Factory) {
f.scope = SCOPE_PROTOTYPE
}
// Scoped identifies the lifecycle of an instance, such as singleton,
// prototype, and so forth.. A scope governs how the container
// reuses instances of the type.
//
// To register additional custom scopes, see Container.RegisterScope.
//
// Defaults to an empty string ("") which implies SCOPE_SINGLETON.
func Scoped(scope string) FactoryConfig {
scope = strings.TrimSpace(scope)
if scope == "" {
scope = SCOPE_SINGLETON
}
return func(f *Factory) {
f.scope = scope
}
}
// Startup indicates that this component must be initialized during
// container initialization (Container.Initialize method)
//
// Example:
//
// di.Register(func() {
// print("Second")
// }, Startup(200))
//
// di.Register(func() {
// print("First")
// }, Startup(100))
func Startup(order int) FactoryConfig {
return func(f *Factory) {
f.order = order
f.startup = true
}
}
// Order can be applied to any component to indicate in what order they
// should be used.
//
// Higher values are interpreted as lower priority. As a consequence,
// the object with the lowest value has the highest priority.
//
// Same order values will result in arbitrary sort positions for the
// affected objects.
//
// If the component is marked as Startup, the order determines its
// execution order.
//
// Order is also used during dependency injection. The candidate with the
// lower order will be injected.
//
// A framework can implement filters and use order to define the order
// of execution
func Order(order int) FactoryConfig {
return func(f *Factory) {
f.order = order
}
}
// Stereotype a stereotype encapsulates any combination of ComponentOption
//
// Example:
//
// var Controller = di.Stereotype(di.Singleton, di.Qualify[testQualifier](), di.Startup(500))
//
// di.Register(func() MyController {
// return &MyController{}
// }, Controller)
//
// Example: Filter using Stereotype
//
// di.Filter(Controller).Foreach(func(f *Factory) (bool, error) { ... })
func Stereotype(options ...FactoryConfig) FactoryConfig {
return func(f *Factory) {
for _, option := range options {
option(f)
}
}
}
// Condition a single condition that must be matched in order for a component to be registered.
// Conditions are checked immediately before the component factory is due to be
// registered and are free to veto registration based on any criteria
// that can be determined at that point.
func Condition(condition ConditionFunc) FactoryConfig {
return func(f *Factory) {
f.conditions = append(f.conditions, condition)
}
}
// @TODO:
// Lazy, Whether lazy initialization should occur.
// DependsOn[AnoterService]()
// PreDestroy(T)