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

fix https://github.com/kataras/iris/issues/1450 and continue on implementing 1449

Former-commit-id: 617f64d061e88f050a443ea1751fa244164656c5
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-02-14 23:34:56 +02:00
parent 09a410c6cb
commit c13fd84354
24 changed files with 581 additions and 144 deletions

View File

@@ -3,6 +3,8 @@ package di
import (
"errors"
"reflect"
"github.com/kataras/iris/v12/context"
)
// BindType is the type of a binded object/value, it's being used to
@@ -35,7 +37,7 @@ type BindObject struct {
Value reflect.Value
BindType BindType
ReturnValue func([]reflect.Value) reflect.Value
ReturnValue func(ctx context.Context) reflect.Value
}
// MakeBindObject accepts any "v" value, struct, pointer or a function
@@ -43,10 +45,10 @@ type BindObject struct {
// or the input arguments (if "v.elem()" is func)
// are valid to be included as the final object's dependencies, even if the caller added more
// the "di" is smart enough to select what each "v" needs and what not before serve time.
func MakeBindObject(v reflect.Value, goodFunc TypeChecker) (b BindObject, err error) {
func MakeBindObject(v reflect.Value, goodFunc TypeChecker, errorHandler ErrorHandler) (b BindObject, err error) {
if IsFunc(v) {
b.BindType = Dynamic
b.ReturnValue, b.Type, err = MakeReturnValue(v, goodFunc)
b.ReturnValue, b.Type, err = MakeReturnValue(v, goodFunc, errorHandler)
} else {
b.BindType = Static
b.Type = v.Type()
@@ -67,9 +69,9 @@ var errBad = errors.New("bad")
// The "fn" can have the following form:
// `func(myService) MyViewModel`.
//
// The return type of the "fn" should be a value instance, not a pointer, for your own protection.
// The binder function should return only one value.
func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Value) reflect.Value, reflect.Type, error) {
// The return type of the "fn" should be a value instance, not a pointer.
// The binder function should return just one value.
func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker, errorHandler ErrorHandler) (func(ctx context.Context) reflect.Value, reflect.Type, error) {
typ := IndirectType(fn.Type())
// invalid if not a func.
@@ -93,32 +95,30 @@ func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Val
firstOutTyp := typ.Out(0)
firstZeroOutVal := reflect.New(firstOutTyp).Elem()
bf := func(ctxValue []reflect.Value) reflect.Value {
results := fn.Call(ctxValue)
bf := func(ctx context.Context) reflect.Value {
results := fn.Call(ctx.ReflectValue())
if n == 2 {
// two, second is always error.
errVal := results[1]
if !errVal.IsNil() {
if errorHandler != nil {
errorHandler.HandleError(ctx, errVal.Interface().(error))
}
return firstZeroOutVal
}
}
v := results[0]
if !v.IsValid() { // check the first value, second is error.
return firstZeroOutVal
}
if n == 2 {
// two, second is always error.
errVal := results[1]
if !errVal.IsNil() {
// error is not nil, do something with it.
if ctx, ok := ctxValue[0].Interface().(interface {
StatusCode(int)
WriteString(string) (int, error)
StopExecution()
}); ok {
ctx.StatusCode(400)
ctx.WriteString(errVal.Interface().(error).Error())
ctx.StopExecution()
}
return firstZeroOutVal
}
}
// if firstOutTyp == reflectValueType {
// converted := v.Convert(typ.In(0))
// fmt.Printf("object.go#124: converted: %#+v\n", converted)
// return converted //reflect.ValueOf(v.Interface())
// }
// if v.String() == "<interface {} Value>" {
// println("di/object.go: " + v.String())
@@ -138,7 +138,7 @@ func (b *BindObject) IsAssignable(to reflect.Type) bool {
// Assign sets the values to a setter, "toSetter" contains the setter, so the caller
// can use it for multiple and different structs/functions as well.
func (b *BindObject) Assign(ctx []reflect.Value, toSetter func(reflect.Value)) {
func (b *BindObject) Assign(ctx context.Context, toSetter func(reflect.Value)) {
if b.BindType == Dynamic {
toSetter(b.ReturnValue(ctx))
return