diff --git a/HISTORY.md b/HISTORY.md index a4c5a6355..f6101ba4c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -371,6 +371,8 @@ Other Improvements: ![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0) +- Fix [#1564](https://github.com/kataras/iris/issues/1564). + - Fix [#1553](https://github.com/kataras/iris/issues/1553). - New `DirOptions.Cache` to cache assets in-memory among with their compressed contents (in order to be ready to served if client ask). Learn more about this feature by reading [all #1556 comments](https://github.com/kataras/iris/issues/1556#issuecomment-661057446). Usage: diff --git a/hero/binding.go b/hero/binding.go index e2377cd24..df5bb8acc 100644 --- a/hero/binding.go +++ b/hero/binding.go @@ -279,8 +279,12 @@ func getBindingsForStruct(v reflect.Value, dependencies []*Dependency, paramsCou // 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 | Stateless : %d\n", typ, n, len(exportedBindings), stateless) + // for i, b := range exportedBindings { + // fmt.Printf("[%d] [Static=%v] %s\n", i, b.Dependency.Static, b.Dependency.DestType) + // } if stateless == 0 && len(nonZero) >= len(exportedBindings) { // if we have not a single stateless and fields are defined then just return. diff --git a/hero/dependency.go b/hero/dependency.go index 9fb0b920a..5d960ff6c 100644 --- a/hero/dependency.go +++ b/hero/dependency.go @@ -208,9 +208,28 @@ func fromDependentFunc(v reflect.Value, dest *Dependency, funcDependencies []*De } bindings := getBindingsForFunc(v, funcDependencies, -1 /* parameter bindings are disabled for depent dependencies */) + numIn := typ.NumIn() numOut := typ.NumOut() + // d1 = Logger + // d2 = func(Logger) S1 + // d2 should be static: it accepts dependencies that are static + // (note: we don't check the output argument(s) of this dependnecy). + if numIn == len(bindings) { + static := true + for _, b := range bindings { + if !b.Dependency.Static && matchDependency(b.Dependency, typ.In(b.Input.Index)) { + static = false + break + } + } + + if static { + dest.Static = static + } + } + firstOutIsError := numOut == 1 && isError(typ.Out(0)) secondOutIsError := numOut == 2 && isError(typ.Out(1)) @@ -241,5 +260,6 @@ func fromDependentFunc(v reflect.Value, dest *Dependency, funcDependencies []*De dest.DestType = typ.Out(0) dest.Handle = handler + return true } diff --git a/hero/dependency_test.go b/hero/dependency_test.go index 71ee7c7a5..b90e341e8 100644 --- a/hero/dependency_test.go +++ b/hero/dependency_test.go @@ -168,3 +168,39 @@ func testDependencies(t *testing.T, tests []testDependencyTest) { // t.Logf("[%d] output: %#+v", i, val.Interface()) } } + +func TestDependentDependencyInheritanceStatic(t *testing.T) { + // Tests the following case #1564: + // Logger + // func(Logger) S1 + // ^ Should be static because Logger + // is a structure, a static dependency. + // + // func(Logger) S2 + // func(S1, S2) S3 + // ^ Should be marked as static dependency + // because everything that depends on are static too. + + type S1 struct { + msg string + } + + type S2 struct { + msg2 string + } + + serviceDep := NewDependency(&testServiceImpl{prefix: "1"}) + d1 := NewDependency(func(t testService) S1 { + return S1{t.Say("2")} + }, serviceDep) + if !d1.Static { + t.Fatalf("d1 dependency should be static: %#+v", d1) + } + + d2 := NewDependency(func(t testService, s S1) S2 { + return S2{"3"} + }, serviceDep, d1) + if !d2.Static { + t.Fatalf("d2 dependency should be static: %#+v", d2) + } +}