@@ -3,8 +3,6 @@ package autowire
3
3
import (
4
4
"io"
5
5
"log"
6
- "os"
7
- "os/signal"
8
6
"reflect"
9
7
"regexp"
10
8
"strings"
@@ -13,15 +11,13 @@ import (
13
11
14
12
var dependencies map [string ]interface {}
15
13
var currentProfile = getProfile ()
16
- var ch = make (chan os.Signal )
17
14
18
15
// Tag name
19
16
const Tag = "autowire"
20
17
21
18
func init () {
22
19
log .SetFlags (log .LstdFlags | log .Lshortfile )
23
20
log .Println ("Init Autowire Context" )
24
- signal .Notify (ch , os .Interrupt , os .Kill )
25
21
dependencies = make (map [string ]interface {})
26
22
}
27
23
@@ -34,49 +30,60 @@ func InitProd(initFunc func()) {
34
30
}
35
31
36
32
// Autowire function injects all dependencies for the given structure v.
37
- // In order dependencies to be injected the desired struct fields should be marked with
38
- // autowire tag.
33
+ // Autowire function should be executed in the init() function of the
34
+ // package. In order dependencies to be injected the desired struct fields
35
+ // should be marked with autowire tag.
39
36
//
40
37
// Concrete type Injection
41
38
//
42
39
// Currently both type of fields exported and unexported are supported.
43
40
//
44
41
// Unexported field
45
42
//
46
- // Following snippet shows injecting dependencies inside private structure fields using `autowire:""` tag:
43
+ // Following snippet shows injecting dependencies inside private structure
44
+ // fields using `autowire:""` tag:
47
45
// type Application struct {
48
46
// config *configuration.ApplicationConfig `autowire:""`
49
47
// }
50
48
// func (a *Application) SetConfig(config *configuration.ApplicationConfig) {
51
49
// a.config = config
52
50
// }
53
- // If we need given dependency to be injected into unexported field Setter function(Set<FieldName>) is required, as show above.
54
- // If you have a field called config (lower case, unexported), the setter method should be called SetConfig (upper case, exported), not Setconfig.
51
+ // If we need given dependency to be injected into unexported field Setter
52
+ // function(Set<FieldName>) is required, as show above. If you have a field
53
+ // called config (lower case, unexported), the setter method should be called
54
+ // SetConfig, not Setconfig.
55
55
//
56
56
// Exported field
57
57
//
58
- // The use of upper-case names of the struct fields indicated field is exported.
58
+ // The use of upper-case names of the struct fields indicated that field is exported.
59
59
// type Application struct {
60
60
// Config *configuration.ApplicationConfig `autowire:""`
61
61
// }
62
- // Dependency injection of exported field is supported with the difference that we don`t provide additional Setter function.
62
+ // Dependency injection of exported field is supported with the difference that we don't
63
+ // provide additional Setter function.
63
64
//
64
65
// Interface Injection
65
66
//
66
- // Often it`s better to rely on interface instead of concrete type, in order to accomplish this decoupling we specify
67
- // interfaces as a type of struct fields. The following snippet demonstrate that
67
+ // Often it's better to rely on interface instead of concrete type, in order to
68
+ // accomplish this decoupling we should specify interfaces as a type of struct
69
+ // fields. The following snippet demonstrate that:
68
70
// type UserService struct {
69
71
// userRoleRepository UserRoleRepository `autowire:"repository/InMemoryUserRoleRepository"`
70
72
// }
71
73
// func (u *UserService) SetUserRoleRepository(userRoleRepository UserRoleRepository) {
72
74
// u.userRoleRepository = userRoleRepository
73
75
// }
74
- // UserRoleRepository is simply an interface and InMemoryUserRoleRepository is a struct, which implements this interface.
75
- // As it`s done dependency injection on unexported field, providing Setter is required. Just to highlight unexported fields
76
- // needs Setter while exported not. For more information take a look at example#https://github.com/go-autowire/autowire/tree/main/example package.
77
- // Example:
78
- //
79
- //
76
+ // UserRoleRepository is simply an interface and InMemoryUserRoleRepository is a
77
+ // struct, which implements that interface. As dependency injection is executed
78
+ // on unexported field, providing Setter is required. Just to highlight unexported
79
+ // fields needs Setter while exported not. For more information take a look at
80
+ // example https://github.com/go-autowire/autowire/tree/main/example package.
81
+ // Very Simplified Example:
82
+ // type App struct {}
83
+ // func init() {
84
+ // autowire.Autowire(&App{})
85
+ // }
86
+ // As mentioned above Autowire function should be invoked in the package init function.
80
87
func Autowire (v interface {}) {
81
88
value := reflect .ValueOf (v )
82
89
switch value .Kind () {
@@ -95,12 +102,12 @@ func Autowire(v interface{}) {
95
102
default : // reflect.Array, reflect.Struct, reflect.Interface
96
103
log .Println (value .Type ().String () + " value" )
97
104
}
98
- //log.Println(dependencies)
105
+ // log.Println(dependencies)
99
106
}
100
107
101
108
// Autowired function returns fully initialized with all dependencies instance, which is ready to be used.
102
- //As the result is empty interface, type assertions is required before using the instance.
103
- //Take a look at https://golang.org/ref/spec#Type_assertions for more information.
109
+ // As the result is empty interface, type assertions is required before using the instance.
110
+ // Take a look at https://golang.org/ref/spec#Type_assertions for more information.
104
111
// The following snippet demonstrate how could be done :
105
112
// app := autowire.Autowired(app.Application{}).(*app.Application)
106
113
func Autowired (v interface {}) interface {} {
@@ -121,6 +128,24 @@ func Autowired(v interface{}) interface{} {
121
128
return nil
122
129
}
123
130
131
+ // Close function invoke Close method on each autowired struct
132
+ // which implements io.Closer interface, so currently active
133
+ // occupied resources (connections, channels, descriptor, etc.)
134
+ // could be released.
135
+ func Close () {
136
+ log .Println ("Closing..." )
137
+ for _ , dependency := range dependencies {
138
+ valueDepend := reflect .ValueOf (dependency )
139
+ closerType := reflect .TypeOf ((* io .Closer )(nil )).Elem ()
140
+ if valueDepend .Type ().Implements (closerType ) {
141
+ err := dependency .(io.Closer ).Close ()
142
+ if err != nil {
143
+ log .Println (err .Error ())
144
+ }
145
+ }
146
+ }
147
+ }
148
+
124
149
func getStructPtrFullPath (value reflect.Value ) string {
125
150
return getFullPath (value .Elem ().Type ().PkgPath (), value .Type ().String ())
126
151
}
@@ -191,25 +216,3 @@ func findDependency(tagDependencyType string) []interface{} {
191
216
}
192
217
return result
193
218
}
194
-
195
- // Run executes function function after the function execution completes for each autowired struct
196
- // which implements io.Closer interface will be invoked Call() function, so currently active
197
- //occupied resources(connections, channels, etc.) could be released.
198
- func Run (function func ()) {
199
- defer closeAll ()
200
- function ()
201
- }
202
-
203
- func closeAll () {
204
- log .Println ("Closing..." )
205
- for _ , dependency := range dependencies {
206
- valueDepend := reflect .ValueOf (dependency )
207
- closerType := reflect .TypeOf ((* io .Closer )(nil )).Elem ()
208
- if valueDepend .Type ().Implements (closerType ) {
209
- err := dependency .(io.Closer ).Close ()
210
- if err != nil {
211
- log .Println (err .Error ())
212
- }
213
- }
214
- }
215
- }
0 commit comments