1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-27 05:45:56 +00:00

Update to version 12.1.8 - Read HISTORY.md

Former-commit-id: d3d30cb15537146e3071731be9d674a5cb59de97
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-02-16 11:14:35 +02:00
parent 899aec8b19
commit 08403f0317
21 changed files with 275 additions and 240 deletions

View File

@@ -18,10 +18,10 @@ type (
FuncInjector struct {
// the original function, is being used
// only the .Call, which is referring to the same function, always.
fn reflect.Value
typ reflect.Type
goodFunc TypeChecker
errorHandler ErrorHandler
fn reflect.Value
typ reflect.Type
FallbackBinder FallbackBinder
ErrorHandler ErrorHandler
inputs []*targetFuncInput
// Length is the number of the valid, final binded input arguments.
@@ -51,13 +51,13 @@ func (s *FuncInjector) miss(index int, remaining Values) {
// that the caller should use to bind input arguments of the "fn" function.
//
// The hijack and the goodFunc are optional, the "values" is the dependencies collection.
func MakeFuncInjector(fn reflect.Value, hijack Hijacker, goodFunc TypeChecker, errorHandler ErrorHandler, values ...reflect.Value) *FuncInjector {
func MakeFuncInjector(fn reflect.Value, values ...reflect.Value) *FuncInjector {
typ := IndirectType(fn.Type())
s := &FuncInjector{
fn: fn,
typ: typ,
goodFunc: goodFunc,
errorHandler: errorHandler,
fn: fn,
typ: typ,
FallbackBinder: DefaultFallbackBinder,
ErrorHandler: DefaultErrorHandler,
}
if !IsFunc(typ) {
@@ -71,16 +71,12 @@ func MakeFuncInjector(fn reflect.Value, hijack Hijacker, goodFunc TypeChecker, e
for i := 0; i < n; i++ {
inTyp := typ.In(i)
if hijack != nil {
b, ok := hijack(inTyp)
if ok && b != nil {
s.inputs = append(s.inputs, &targetFuncInput{
InputIndex: i,
Object: b,
})
continue
}
if b, ok := tryBindContext(inTyp); ok {
s.inputs = append(s.inputs, &targetFuncInput{
InputIndex: i,
Object: b,
})
continue
}
matched := false
@@ -98,6 +94,50 @@ func MakeFuncInjector(fn reflect.Value, hijack Hijacker, goodFunc TypeChecker, e
break
}
// TODO: (already working on it) clean up or even re-write the whole di, hero and some of the mvc,
// this is a dirty but working-solution for #1449.
// Limitations:
// - last input argument
// - not able to customize it other than DefaultFallbackBinder on MVC (on hero it can be customized)
// - the "di" package is now depends on context package which is not an import-cycle issue, it's not imported there.
if i == n-1 {
if v.Type() == autoBindingTyp && s.FallbackBinder != nil {
canFallback := true
if k := inTyp.Kind(); k == reflect.Ptr {
if inTyp.Elem().Kind() != reflect.Struct {
canFallback = false
}
} else if k != reflect.Struct {
canFallback = false
}
if canFallback {
matched = true
s.inputs = append(s.inputs, &targetFuncInput{
InputIndex: i,
Object: &BindObject{
Type: inTyp,
BindType: Dynamic,
ReturnValue: func(ctx context.Context) reflect.Value {
value, err := s.FallbackBinder(ctx, OrphanInput{Type: inTyp})
if err != nil {
if s.ErrorHandler != nil {
s.ErrorHandler.HandleError(ctx, err)
}
}
return value
},
},
})
break
}
}
}
}
if !matched {
@@ -108,7 +148,6 @@ func MakeFuncInjector(fn reflect.Value, hijack Hijacker, goodFunc TypeChecker, e
// with different set of binding "values".
s.miss(i, values) // send the remaining dependencies values.
}
}
return s
@@ -119,6 +158,11 @@ func (s *FuncInjector) refresh() {
s.Has = s.Length > 0
}
// AutoBindingValue a fake type to expliclty set the return value of hero.AutoBinding.
type AutoBindingValue struct{}
var autoBindingTyp = reflect.TypeOf(AutoBindingValue{})
func (s *FuncInjector) addValue(inputIndex int, value reflect.Value) bool {
defer s.refresh()
@@ -129,31 +173,14 @@ func (s *FuncInjector) addValue(inputIndex int, value reflect.Value) bool {
inTyp := s.typ.In(inputIndex)
// the binded values to the func's inputs.
b, err := MakeBindObject(value, s.goodFunc, s.errorHandler)
b, err := MakeBindObject(value, s.ErrorHandler)
if err != nil {
return false
}
// TODO: expose that (need to push a fix for issue #1450 first)
if b.Type == reflectValueType {
b.Type = inTyp
// returnValue := b.ReturnValue
b.ReturnValue = func(ctx context.Context) reflect.Value {
newValue := reflect.New(inTyp)
if err := ctx.ReadJSON(newValue.Interface()); err != nil {
if s.errorHandler != nil {
s.errorHandler.HandleError(ctx, err)
}
}
return newValue.Elem()
}
}
if b.IsAssignable(inTyp) {
// fmt.Printf("binded input index: %d for type: %s and value: %v with pointer: %v\n",
// i, b.Type.String(), inTyp.String(), inTyp.Pointer())
// fmt.Printf("binded input index: %d for type: %s and value: %v with dependency: %v\n",
// inputIndex, b.Type.String(), inTyp.String(), b)
s.inputs = append(s.inputs, &targetFuncInput{
InputIndex: inputIndex,
Object: &b,
@@ -164,12 +191,6 @@ func (s *FuncInjector) addValue(inputIndex int, value reflect.Value) bool {
return false
}
// ErrorHandler registers an error handler for this FuncInjector.
func (s *FuncInjector) ErrorHandler(errorHandler ErrorHandler) *FuncInjector {
s.errorHandler = errorHandler
return s
}
// Retry used to add missing dependencies, i.e path parameter builtin bindings if not already exists
// in the `hero.Handler`, once, only for that func injector.
func (s *FuncInjector) Retry(retryFn func(inIndex int, inTyp reflect.Type, remainingValues Values) (reflect.Value, bool)) bool {