mirror of
https://github.com/kataras/iris.git
synced 2025-12-24 05:17:03 +00:00
MVC improvements: add HandleWebsocket that now registers events automatically based on the struct's methods(!) and fix a bug when more than one value of the same type is registered to a static field of a controller
Former-commit-id: e369d1426ac1a6b58314930a18362670317da3c1
This commit is contained in:
@@ -20,6 +20,22 @@ const (
|
||||
Singleton
|
||||
)
|
||||
|
||||
// read-only on runtime.
|
||||
var scopeNames = map[Scope]string{
|
||||
Stateless: "Stateless",
|
||||
Singleton: "Singleton",
|
||||
}
|
||||
|
||||
// Return "Stateless" for 0 or "Singleton" for 1.
|
||||
func (scope Scope) String() string {
|
||||
name, ok := scopeNames[scope]
|
||||
if !ok {
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
type (
|
||||
targetStructField struct {
|
||||
Object *BindObject
|
||||
@@ -65,6 +81,20 @@ func MakeStructInjector(v reflect.Value, hijack Hijacker, goodFunc TypeChecker,
|
||||
elemType: IndirectType(v.Type()),
|
||||
}
|
||||
|
||||
// Optionally check and keep good values only here,
|
||||
// but not required because they are already checked by users of this function.
|
||||
//
|
||||
// for i, v := range values {
|
||||
// if !goodVal(v) || IsZero(v) {
|
||||
// if last := len(values) - 1; last > i {
|
||||
// values = append(values[:i], values[i+1:]...)
|
||||
// } else {
|
||||
// values = values[0:last]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
visited := make(map[int]struct{}, 0) // add a visited to not add twice a single value (09-Jul-2019).
|
||||
fields := lookupFields(s.elemType, true, nil)
|
||||
for _, f := range fields {
|
||||
if hijack != nil {
|
||||
@@ -78,15 +108,19 @@ func MakeStructInjector(v reflect.Value, hijack Hijacker, goodFunc TypeChecker,
|
||||
}
|
||||
}
|
||||
|
||||
for _, val := range values {
|
||||
for idx, val := range values {
|
||||
if _, alreadySet := visited[idx]; alreadySet {
|
||||
continue
|
||||
}
|
||||
|
||||
// the binded values to the struct's fields.
|
||||
b, err := MakeBindObject(val, goodFunc)
|
||||
|
||||
if err != nil {
|
||||
return s // if error stop here.
|
||||
}
|
||||
|
||||
if b.IsAssignable(f.Type) {
|
||||
visited[idx] = struct{}{}
|
||||
// fmt.Printf("bind the object to the field: %s at index: %#v and type: %s\n", f.Name, f.Index, f.Type.String())
|
||||
s.fields = append(s.fields, &targetStructField{
|
||||
FieldIndex: f.Index,
|
||||
@@ -126,13 +160,14 @@ func (s *StructInjector) setState() {
|
||||
// if so then set the temp staticBindingsFieldsLength to that number, so for example:
|
||||
// if static binding length is 0
|
||||
// but an unexported field is set-ed then act that as singleton.
|
||||
|
||||
if allStructFieldsLength > staticBindingsFieldsLength {
|
||||
structFieldsUnexportedNonZero := LookupNonZeroFieldsValues(s.initRef, false)
|
||||
staticBindingsFieldsLength = len(structFieldsUnexportedNonZero)
|
||||
}
|
||||
|
||||
// println("staticBindingsFieldsLength: ", staticBindingsFieldsLength)
|
||||
// println("allStructFieldsLength: ", allStructFieldsLength)
|
||||
// println("staticBindingsFieldsLength: ", staticBindingsFieldsLength)
|
||||
|
||||
// if the number of static values binded is equal to the
|
||||
// total struct's fields(including unexported fields this time) then set as singleton.
|
||||
@@ -169,9 +204,23 @@ func (s *StructInjector) fillStruct() {
|
||||
func (s *StructInjector) String() (trace string) {
|
||||
for i, f := range s.fields {
|
||||
elemField := s.elemType.FieldByIndex(f.FieldIndex)
|
||||
trace += fmt.Sprintf("[%d] %s binding: '%s' for field '%s %s'\n",
|
||||
i+1, bindTypeString(f.Object.BindType), f.Object.Type.String(),
|
||||
elemField.Name, elemField.Type.String())
|
||||
|
||||
format := "\t[%d] %s binding: %#+v for field '%s %s'"
|
||||
if len(s.fields) > i+1 {
|
||||
format += "\n"
|
||||
}
|
||||
|
||||
if !f.Object.Value.IsValid() {
|
||||
continue // probably a Context.
|
||||
}
|
||||
|
||||
valuePresent := f.Object.Value.Interface()
|
||||
|
||||
if f.Object.BindType == Dynamic {
|
||||
valuePresent = f.Object.Type.String()
|
||||
}
|
||||
|
||||
trace += fmt.Sprintf(format, i+1, bindTypeString(f.Object.BindType), valuePresent, elemField.Name, elemField.Type.String())
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user