You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
7.6 KiB

  1. // Copyright 2013 Jeremy Saenz
  2. // Copyright 2015 The Macaron Authors
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  5. // not use this file except in compliance with the License. You may obtain
  6. // a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. // License for the specific language governing permissions and limitations
  14. // under the License.
  15. // Package inject provides utilities for mapping and injecting dependencies in various ways.
  16. package inject
  17. import (
  18. "fmt"
  19. "reflect"
  20. )
  21. // Injector represents an interface for mapping and injecting dependencies into structs
  22. // and function arguments.
  23. type Injector interface {
  24. Applicator
  25. Invoker
  26. TypeMapper
  27. // SetParent sets the parent of the injector. If the injector cannot find a
  28. // dependency in its Type map it will check its parent before returning an
  29. // error.
  30. SetParent(Injector)
  31. }
  32. // Applicator represents an interface for mapping dependencies to a struct.
  33. type Applicator interface {
  34. // Maps dependencies in the Type map to each field in the struct
  35. // that is tagged with 'inject'. Returns an error if the injection
  36. // fails.
  37. Apply(interface{}) error
  38. }
  39. // Invoker represents an interface for calling functions via reflection.
  40. type Invoker interface {
  41. // Invoke attempts to call the interface{} provided as a function,
  42. // providing dependencies for function arguments based on Type. Returns
  43. // a slice of reflect.Value representing the returned values of the function.
  44. // Returns an error if the injection fails.
  45. Invoke(interface{}) ([]reflect.Value, error)
  46. }
  47. // FastInvoker represents an interface in order to avoid the calling function via reflection.
  48. //
  49. // example:
  50. // type handlerFuncHandler func(http.ResponseWriter, *http.Request) error
  51. // func (f handlerFuncHandler)Invoke([]interface{}) ([]reflect.Value, error){
  52. // ret := f(p[0].(http.ResponseWriter), p[1].(*http.Request))
  53. // return []reflect.Value{reflect.ValueOf(ret)}, nil
  54. // }
  55. //
  56. // type funcHandler func(int, string)
  57. // func (f funcHandler)Invoke([]interface{}) ([]reflect.Value, error){
  58. // f(p[0].(int), p[1].(string))
  59. // return nil, nil
  60. // }
  61. type FastInvoker interface {
  62. // Invoke attempts to call the ordinary functions. If f is a function
  63. // with the appropriate signature, f.Invoke([]interface{}) is a Call that calls f.
  64. // Returns a slice of reflect.Value representing the returned values of the function.
  65. // Returns an error if the injection fails.
  66. Invoke([]interface{}) ([]reflect.Value, error)
  67. }
  68. // IsFastInvoker check interface is FastInvoker
  69. func IsFastInvoker(h interface{}) bool {
  70. _, ok := h.(FastInvoker)
  71. return ok
  72. }
  73. // TypeMapper represents an interface for mapping interface{} values based on type.
  74. type TypeMapper interface {
  75. // Maps the interface{} value based on its immediate type from reflect.TypeOf.
  76. Map(interface{}) TypeMapper
  77. // Maps the interface{} value based on the pointer of an Interface provided.
  78. // This is really only useful for mapping a value as an interface, as interfaces
  79. // cannot at this time be referenced directly without a pointer.
  80. MapTo(interface{}, interface{}) TypeMapper
  81. // Provides a possibility to directly insert a mapping based on type and value.
  82. // This makes it possible to directly map type arguments not possible to instantiate
  83. // with reflect like unidirectional channels.
  84. Set(reflect.Type, reflect.Value) TypeMapper
  85. // Returns the Value that is mapped to the current type. Returns a zeroed Value if
  86. // the Type has not been mapped.
  87. GetVal(reflect.Type) reflect.Value
  88. }
  89. type injector struct {
  90. values map[reflect.Type]reflect.Value
  91. parent Injector
  92. }
  93. // InterfaceOf dereferences a pointer to an Interface type.
  94. // It panics if value is not an pointer to an interface.
  95. func InterfaceOf(value interface{}) reflect.Type {
  96. t := reflect.TypeOf(value)
  97. for t.Kind() == reflect.Ptr {
  98. t = t.Elem()
  99. }
  100. if t.Kind() != reflect.Interface {
  101. panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
  102. }
  103. return t
  104. }
  105. // New returns a new Injector.
  106. func New() Injector {
  107. return &injector{
  108. values: make(map[reflect.Type]reflect.Value),
  109. }
  110. }
  111. // Invoke attempts to call the interface{} provided as a function,
  112. // providing dependencies for function arguments based on Type.
  113. // Returns a slice of reflect.Value representing the returned values of the function.
  114. // Returns an error if the injection fails.
  115. // It panics if f is not a function
  116. func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
  117. t := reflect.TypeOf(f)
  118. switch v := f.(type) {
  119. case FastInvoker:
  120. return inj.fastInvoke(v, t, t.NumIn())
  121. default:
  122. return inj.callInvoke(f, t, t.NumIn())
  123. }
  124. }
  125. func (inj *injector) fastInvoke(f FastInvoker, t reflect.Type, numIn int) ([]reflect.Value, error) {
  126. var in []interface{}
  127. if numIn > 0 {
  128. in = make([]interface{}, numIn) // Panic if t is not kind of Func
  129. var argType reflect.Type
  130. var val reflect.Value
  131. for i := 0; i < numIn; i++ {
  132. argType = t.In(i)
  133. val = inj.GetVal(argType)
  134. if !val.IsValid() {
  135. return nil, fmt.Errorf("Value not found for type %v", argType)
  136. }
  137. in[i] = val.Interface()
  138. }
  139. }
  140. return f.Invoke(in)
  141. }
  142. // callInvoke reflect.Value.Call
  143. func (inj *injector) callInvoke(f interface{}, t reflect.Type, numIn int) ([]reflect.Value, error) {
  144. var in []reflect.Value
  145. if numIn > 0 {
  146. in = make([]reflect.Value, numIn)
  147. var argType reflect.Type
  148. var val reflect.Value
  149. for i := 0; i < numIn; i++ {
  150. argType = t.In(i)
  151. val = inj.GetVal(argType)
  152. if !val.IsValid() {
  153. return nil, fmt.Errorf("Value not found for type %v", argType)
  154. }
  155. in[i] = val
  156. }
  157. }
  158. return reflect.ValueOf(f).Call(in), nil
  159. }
  160. // Maps dependencies in the Type map to each field in the struct
  161. // that is tagged with 'inject'.
  162. // Returns an error if the injection fails.
  163. func (inj *injector) Apply(val interface{}) error {
  164. v := reflect.ValueOf(val)
  165. for v.Kind() == reflect.Ptr {
  166. v = v.Elem()
  167. }
  168. if v.Kind() != reflect.Struct {
  169. return nil // Should not panic here ?
  170. }
  171. t := v.Type()
  172. for i := 0; i < v.NumField(); i++ {
  173. f := v.Field(i)
  174. structField := t.Field(i)
  175. if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
  176. ft := f.Type()
  177. v := inj.GetVal(ft)
  178. if !v.IsValid() {
  179. return fmt.Errorf("Value not found for type %v", ft)
  180. }
  181. f.Set(v)
  182. }
  183. }
  184. return nil
  185. }
  186. // Maps the concrete value of val to its dynamic type using reflect.TypeOf,
  187. // It returns the TypeMapper registered in.
  188. func (i *injector) Map(val interface{}) TypeMapper {
  189. i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
  190. return i
  191. }
  192. func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
  193. i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
  194. return i
  195. }
  196. // Maps the given reflect.Type to the given reflect.Value and returns
  197. // the Typemapper the mapping has been registered in.
  198. func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
  199. i.values[typ] = val
  200. return i
  201. }
  202. func (i *injector) GetVal(t reflect.Type) reflect.Value {
  203. val := i.values[t]
  204. if val.IsValid() {
  205. return val
  206. }
  207. // no concrete types found, try to find implementors
  208. // if t is an interface
  209. if t.Kind() == reflect.Interface {
  210. for k, v := range i.values {
  211. if k.Implements(t) {
  212. val = v
  213. break
  214. }
  215. }
  216. }
  217. // Still no type found, try to look it up on the parent
  218. if !val.IsValid() && i.parent != nil {
  219. val = i.parent.GetVal(t)
  220. }
  221. return val
  222. }
  223. func (i *injector) SetParent(parent Injector) {
  224. i.parent = parent
  225. }