inject.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. // TypeMapper represents an interface for mapping interface{} values based on type.
  48. type TypeMapper interface {
  49. // Maps the interface{} value based on its immediate type from reflect.TypeOf.
  50. Map(interface{}) TypeMapper
  51. // Maps the interface{} value based on the pointer of an Interface provided.
  52. // This is really only useful for mapping a value as an interface, as interfaces
  53. // cannot at this time be referenced directly without a pointer.
  54. MapTo(interface{}, interface{}) TypeMapper
  55. // Provides a possibility to directly insert a mapping based on type and value.
  56. // This makes it possible to directly map type arguments not possible to instantiate
  57. // with reflect like unidirectional channels.
  58. Set(reflect.Type, reflect.Value) TypeMapper
  59. // Returns the Value that is mapped to the current type. Returns a zeroed Value if
  60. // the Type has not been mapped.
  61. GetVal(reflect.Type) reflect.Value
  62. }
  63. type injector struct {
  64. values map[reflect.Type]reflect.Value
  65. parent Injector
  66. }
  67. // InterfaceOf dereferences a pointer to an Interface type.
  68. // It panics if value is not an pointer to an interface.
  69. func InterfaceOf(value interface{}) reflect.Type {
  70. t := reflect.TypeOf(value)
  71. for t.Kind() == reflect.Ptr {
  72. t = t.Elem()
  73. }
  74. if t.Kind() != reflect.Interface {
  75. panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
  76. }
  77. return t
  78. }
  79. // New returns a new Injector.
  80. func New() Injector {
  81. return &injector{
  82. values: make(map[reflect.Type]reflect.Value),
  83. }
  84. }
  85. // Invoke attempts to call the interface{} provided as a function,
  86. // providing dependencies for function arguments based on Type.
  87. // Returns a slice of reflect.Value representing the returned values of the function.
  88. // Returns an error if the injection fails.
  89. // It panics if f is not a function
  90. func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
  91. t := reflect.TypeOf(f)
  92. var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func
  93. for i := 0; i < t.NumIn(); i++ {
  94. argType := t.In(i)
  95. val := inj.GetVal(argType)
  96. if !val.IsValid() {
  97. return nil, fmt.Errorf("Value not found for type %v", argType)
  98. }
  99. in[i] = val
  100. }
  101. return reflect.ValueOf(f).Call(in), nil
  102. }
  103. // Maps dependencies in the Type map to each field in the struct
  104. // that is tagged with 'inject'.
  105. // Returns an error if the injection fails.
  106. func (inj *injector) Apply(val interface{}) error {
  107. v := reflect.ValueOf(val)
  108. for v.Kind() == reflect.Ptr {
  109. v = v.Elem()
  110. }
  111. if v.Kind() != reflect.Struct {
  112. return nil // Should not panic here ?
  113. }
  114. t := v.Type()
  115. for i := 0; i < v.NumField(); i++ {
  116. f := v.Field(i)
  117. structField := t.Field(i)
  118. if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
  119. ft := f.Type()
  120. v := inj.GetVal(ft)
  121. if !v.IsValid() {
  122. return fmt.Errorf("Value not found for type %v", ft)
  123. }
  124. f.Set(v)
  125. }
  126. }
  127. return nil
  128. }
  129. // Maps the concrete value of val to its dynamic type using reflect.TypeOf,
  130. // It returns the TypeMapper registered in.
  131. func (i *injector) Map(val interface{}) TypeMapper {
  132. i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
  133. return i
  134. }
  135. func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
  136. i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
  137. return i
  138. }
  139. // Maps the given reflect.Type to the given reflect.Value and returns
  140. // the Typemapper the mapping has been registered in.
  141. func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
  142. i.values[typ] = val
  143. return i
  144. }
  145. func (i *injector) GetVal(t reflect.Type) reflect.Value {
  146. val := i.values[t]
  147. if val.IsValid() {
  148. return val
  149. }
  150. // no concrete types found, try to find implementors
  151. // if t is an interface
  152. if t.Kind() == reflect.Interface {
  153. for k, v := range i.values {
  154. if k.Implements(t) {
  155. val = v
  156. break
  157. }
  158. }
  159. }
  160. // Still no type found, try to look it up on the parent
  161. if !val.IsValid() && i.parent != nil {
  162. val = i.parent.GetVal(t)
  163. }
  164. return val
  165. }
  166. func (i *injector) SetParent(parent Injector) {
  167. i.parent = parent
  168. }