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

OK, my dream-idea is implemented. TODO: Some examples and doc.go is not updated yet, comments on the mvc/di subpackage, the tutorial/vuejs-todo-mvc is running but not finished yet (it's using browser's localstorage and it should be replaced by the http requests that are registered via iris mvc

Former-commit-id: 0ea7e01ce1d78bcb78b40f3b0f5c03ad7c9abaea
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-12-16 06:38:28 +02:00
parent 55dfd195e0
commit 34664aa311
41 changed files with 437 additions and 408 deletions

97
mvc/di/object.go Normal file
View File

@@ -0,0 +1,97 @@
package di
import (
"errors"
"reflect"
)
type BindType uint32
const (
Static BindType = iota // simple assignable value, a static value.
Dynamic // dynamic value, depends on some input arguments from the caller.
)
type BindObject struct {
Type reflect.Type // the Type of 'Value' or the type of the returned 'ReturnValue' .
Value reflect.Value
BindType BindType
ReturnValue func([]reflect.Value) reflect.Value
}
func MakeBindObject(v reflect.Value, goodFunc TypeChecker) (b BindObject, err error) {
if IsFunc(v) {
b.BindType = Dynamic
b.ReturnValue, b.Type, err = MakeReturnValue(v, goodFunc)
} else {
b.BindType = Static
b.Type = v.Type()
b.Value = v
}
return
}
var errBad = errors.New("bad")
// MakeReturnValue takes any function
// that accept custom values and returns something,
// it returns a binder function, which accepts a slice of reflect.Value
// and returns a single one reflect.Value for that.
// It's being used to resolve the input parameters on a "x" consumer faster.
//
// 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) {
typ := IndirectType(fn.Type())
// invalid if not a func.
if typ.Kind() != reflect.Func {
return nil, typ, errBad
}
// invalid if not returns one single value.
if typ.NumOut() != 1 {
return nil, typ, errBad
}
if goodFunc != nil {
if !goodFunc(typ) {
return nil, typ, errBad
}
}
outTyp := typ.Out(0)
zeroOutVal := reflect.New(outTyp).Elem()
bf := func(ctxValue []reflect.Value) reflect.Value {
results := fn.Call(ctxValue)
if len(results) == 0 {
return zeroOutVal
}
v := results[0]
if !v.IsValid() {
return zeroOutVal
}
return v
}
return bf, outTyp, nil
}
func (b *BindObject) IsAssignable(to reflect.Type) bool {
return equalTypes(b.Type, to)
}
func (b *BindObject) Assign(ctx []reflect.Value, toSetter func(reflect.Value)) {
if b.BindType == Dynamic {
toSetter(b.ReturnValue(ctx))
return
}
toSetter(b.Value)
}