1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-18 18:37:05 +00:00

fix #2158 and more

This commit is contained in:
Gerasimos (Makis) Maropoulos
2023-07-08 02:08:18 +03:00
parent 757e7fe61b
commit 6add1ba49b
79 changed files with 551 additions and 467 deletions

View File

@@ -2,6 +2,7 @@ package hero
import (
"fmt"
"strings"
"reflect"
@@ -71,7 +72,7 @@ func newDependency(dependency interface{}, disablePayloadAutoBinding bool, match
}
if d, ok := dependency.(*Dependency); ok {
// already a *Dependency.
// already a *Dependency, do not continue (and most importatly do not call resolveDependency) .
return d
}
@@ -100,11 +101,12 @@ func newDependency(dependency interface{}, disablePayloadAutoBinding bool, match
// DependencyResolver func(v reflect.Value, dest *Dependency) bool
// Resolver DependencyResolver
func resolveDependency(v reflect.Value, disablePayloadAutoBinding bool, dest *Dependency, funcDependencies ...*Dependency) bool {
func resolveDependency(v reflect.Value, disablePayloadAutoBinding bool, dest *Dependency, prevDependencies ...*Dependency) bool {
return fromDependencyHandler(v, dest) ||
fromStructValue(v, dest) ||
fromBuiltinValue(v, dest) ||
fromStructValueOrDependentStructValue(v, disablePayloadAutoBinding, dest, prevDependencies) ||
fromFunc(v, dest) ||
len(funcDependencies) > 0 && fromDependentFunc(v, disablePayloadAutoBinding, dest, funcDependencies)
len(prevDependencies) > 0 && fromDependentFunc(v, disablePayloadAutoBinding, dest, prevDependencies)
}
func fromDependencyHandler(_ reflect.Value, dest *Dependency) bool {
@@ -131,20 +133,114 @@ func fromDependencyHandler(_ reflect.Value, dest *Dependency) bool {
return true
}
func fromStructValue(v reflect.Value, dest *Dependency) bool {
if !isFunc(v) {
// It's just a static value.
handler := func(*context.Context, *Input) (reflect.Value, error) {
return v, nil
}
dest.DestType = v.Type()
dest.Static = true
dest.Handle = handler
return true
func fromBuiltinValue(v reflect.Value, dest *Dependency) bool {
if !isBuiltinValue(v) {
return false
}
return false
// It's just a static builtin value.
handler := func(*context.Context, *Input) (reflect.Value, error) {
return v, nil
}
dest.DestType = v.Type()
dest.Static = true
dest.Handle = handler
return true
}
func fromStructValue(v reflect.Value, dest *Dependency) bool {
if !isStructValue(v) {
return false
}
// It's just a static struct value.
handler := func(*context.Context, *Input) (reflect.Value, error) {
return v, nil
}
dest.DestType = v.Type()
dest.Static = true
dest.Handle = handler
return true
}
func fromStructValueOrDependentStructValue(v reflect.Value, disablePayloadAutoBinding bool, dest *Dependency, prevDependencies []*Dependency) bool {
if !isStructValue(v) {
// It's not just a static struct value.
return false
}
if len(prevDependencies) == 0 { // As a non depedent struct.
// We must make this check so we can avoid the auto-filling of
// the dependencies from Iris builtin dependencies.
return fromStructValue(v, dest)
}
// Check if it's a builtin dependency (e.g an MVC Application (see mvc.go#newApp)),
// if it's and registered without a Dependency wrapper, like the rest builtin dependencies,
// then do NOT try to resolve its fields.
if strings.HasPrefix(indirectType(v.Type()).PkgPath(), "github.com/kataras/iris/v12") {
return fromStructValue(v, dest)
}
bindings := getBindingsForStruct(v, prevDependencies, false, disablePayloadAutoBinding, DefaultDependencyMatcher, -1, nil)
if len(bindings) == 0 {
return fromStructValue(v, dest) // same as above.
}
// As a depedent struct, however we may need to resolve its dependencies first
// so we can decide if it's really a depedent struct or not.
var (
handler = func(*context.Context, *Input) (reflect.Value, error) {
return v, nil
}
isStatic = true
)
for _, binding := range bindings {
if !binding.Dependency.Static {
isStatic = false
break
}
}
handler = func(ctx *context.Context, _ *Input) (reflect.Value, error) { // Called once per dependency on build-time if the dependency is static.
elem := v
if elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
for _, binding := range bindings {
field := elem.FieldByIndex(binding.Input.StructFieldIndex)
if !field.CanSet() || !field.IsZero() {
continue // already set.
}
// if !binding.Dependency.Match(field.Type()) { A check already happen in getBindingsForStruct.
// continue
// }
input, err := binding.Dependency.Handle(ctx, binding.Input)
if err != nil {
if err == ErrSeeOther {
continue
}
return emptyValue, err
}
// fmt.Printf("binding %s to %#+v\n", field.String(), input)
field.Set(input)
}
return v, nil
}
dest.DestType = v.Type()
dest.Static = isStatic
dest.Handle = handler
return true
}
func fromFunc(v reflect.Value, dest *Dependency) bool {