diff --git a/_examples/mvc/websocket/main.go b/_examples/mvc/websocket/main.go index 12c68f8a..354e1c5d 100644 --- a/_examples/mvc/websocket/main.go +++ b/_examples/mvc/websocket/main.go @@ -14,7 +14,7 @@ func main() { app.Logger().SetLevel("debug") // load templates. - app.RegisterView(iris.HTML("./views", ".html")) + // app.RegisterView(iris.HTML("./views", ".html")) // render the ./browser/index.html. app.HandleDir("/", "./browser") diff --git a/hero/binding.go b/hero/binding.go index 4944e40d..e2377cd2 100644 --- a/hero/binding.go +++ b/hero/binding.go @@ -265,7 +265,7 @@ func getBindingsForStruct(v reflect.Value, dependencies []*Dependency, paramsCou }) } - fields := lookupFields(elem, true, true, nil) + fields, stateless := lookupFields(elem, true, true, nil) n := len(fields) if n > 1 && sorter != nil { @@ -276,19 +276,23 @@ func getBindingsForStruct(v reflect.Value, dependencies []*Dependency, paramsCou inputs := make([]reflect.Type, n) for i := 0; i < n; i++ { - // fmt.Printf("Controller [%s] | Field Index: %v | Field Type: %s\n", typ, fields[i].Index, fields[i].Type) + // fmt.Printf("Controller [%s] | Field Index: %v | Field Type: %s\n", typ, fields[i].Index, fields[i].Type) inputs[i] = fields[i].Type } exportedBindings := getBindingsFor(inputs, dependencies, paramsCount) + // fmt.Printf("Controller [%s] | Inputs length: %d vs Bindings length: %d\n", typ, n, len(exportedBindings)) - // fmt.Printf("Controller [%s] Inputs length: %d vs Bindings length: %d\n", typ, n, len(exportedBindings)) - if len(nonZero) >= len(exportedBindings) { // if all are fields are defined then just return. + if stateless == 0 && len(nonZero) >= len(exportedBindings) { + // if we have not a single stateless and fields are defined then just return. + // Note(@kataras): this can accept further improvements. return } // get declared bindings from deps. bindings = append(bindings, exportedBindings...) for _, binding := range bindings { + // fmt.Printf(""Controller [%s] | Binding: %s\n", typ, binding.String()) + if len(binding.Input.StructFieldIndex) == 0 { // set correctly the input's field index. structFieldIndex := fields[binding.Input.Index].Index @@ -296,8 +300,7 @@ func getBindingsForStruct(v reflect.Value, dependencies []*Dependency, paramsCou } // fmt.Printf("Controller [%s] | binding Index: %v | binding Type: %s\n", typ, binding.Input.StructFieldIndex, binding.Input.Type) - - // fmt.Printf("Controller [%s] Set [%s] to struct field index: %v\n", typ.String(), binding.Input.Type.String(), structFieldIndex) + // fmt.Printf("Controller [%s] Set [%s] to struct field index: %v\n", typ.String(), binding.Input.Type.String(), binding.Input.StructFieldIndex) } return diff --git a/hero/reflect.go b/hero/reflect.go index 7865a4aa..3db0a99d 100644 --- a/hero/reflect.go +++ b/hero/reflect.go @@ -101,22 +101,34 @@ func structFieldIgnored(f reflect.StructField) bool { return true // if not anonymous(embedded), ignore it. } - s := f.Tag.Get("ignore") - return s == "true" // if has an ignore tag then ignore it. + if s := f.Tag.Get("ignore"); s == "true" { + return true + } + + if s := f.Tag.Get("stateless"); s == "true" { + return true + } + + return false } // all except non-zero. -func lookupFields(elem reflect.Value, skipUnexported bool, onlyZeros bool, parentIndex []int) (fields []reflect.StructField) { +func lookupFields(elem reflect.Value, skipUnexported bool, onlyZeros bool, parentIndex []int) (fields []reflect.StructField, stateless int) { elemTyp := elem.Type() for i, n := 0, elem.NumField(); i < n; i++ { + field := elemTyp.Field(i) fieldValue := elem.Field(i) - field := elemTyp.Field(i) - // embed any fields from other structs. - if indirectType(field.Type).Kind() == reflect.Struct && !structFieldIgnored(field) { - fields = append(fields, lookupFields(fieldValue, skipUnexported, onlyZeros, append(parentIndex, i))...) - continue + if indirectType(field.Type).Kind() == reflect.Struct { + if structFieldIgnored(field) { + stateless++ // don't skip the loop yet, e.g. iris.Context. + } else { + structFields, statelessN := lookupFields(fieldValue, skipUnexported, onlyZeros, append(parentIndex, i)) + stateless += statelessN + fields = append(fields, structFields...) + continue + } } if onlyZeros && !isZero(fieldValue) { @@ -144,7 +156,7 @@ func lookupFields(elem reflect.Value, skipUnexported bool, onlyZeros bool, paren } func lookupNonZeroFieldValues(elem reflect.Value) (nonZeroFields []reflect.StructField) { - fields := lookupFields(elem, true, false, nil) + fields, _ := lookupFields(elem, true, false, nil) for _, f := range fields { if fieldVal := elem.FieldByIndex(f.Index); goodVal(fieldVal) && !isZero(fieldVal) { /* && f.Type.Kind() == reflect.Ptr &&*/