The ActionValueBinderTracer unconditionally wraps an HttpActionBindingTracer around whatever object is returned from its innerBinder.GetBinding. If the binding has already been wrapped with a tracer, it gets wrapped again.
The ActionValueBinderTracer should not wrap another tracer around the results of GetBinding() if it is already a tracer.
Comments: This double wrapping happens when using OData because attributes like ODataFormatterAttribute are *lazily* initialized, and they are initialized *after* the tracing layer has already initialized. The ODataFormatterAttribute replaces the ActionValueBinder service (already wrapped) with a PerRequestActionValueBinder that delegates to its inner binder. But because the inner binder is the ActionValueBinderTracer, the bindings it returns are wrapped with tracers. The net result is double wrapping. To repro: 1) Make a standard vanilla WebApi app with VS 2) Add [ODataFormatter] to the ValuesController (I know -- you don't need to use OData to trigger this) 3) Add the Tracing NuGet package to enable tracing 4) Set a breakpoint on ActionValueBinderTracer.GetBinding where it creates a new HttpActionBindingTracer. 5) Start the app 6) Use Fiddler to hit the api/Values controller with a GET 7) In time, the breakpoint will be triggered, and the inner binder the tracer is about to wrap is already a tracer. The net effect is of course double tracing. More importantly, it is chaining multiple continuations together.
The ActionValueBinderTracer should not wrap another tracer around the results of GetBinding() if it is already a tracer.
Comments: This double wrapping happens when using OData because attributes like ODataFormatterAttribute are *lazily* initialized, and they are initialized *after* the tracing layer has already initialized. The ODataFormatterAttribute replaces the ActionValueBinder service (already wrapped) with a PerRequestActionValueBinder that delegates to its inner binder. But because the inner binder is the ActionValueBinderTracer, the bindings it returns are wrapped with tracers. The net result is double wrapping. To repro: 1) Make a standard vanilla WebApi app with VS 2) Add [ODataFormatter] to the ValuesController (I know -- you don't need to use OData to trigger this) 3) Add the Tracing NuGet package to enable tracing 4) Set a breakpoint on ActionValueBinderTracer.GetBinding where it creates a new HttpActionBindingTracer. 5) Start the app 6) Use Fiddler to hit the api/Values controller with a GET 7) In time, the breakpoint will be triggered, and the inner binder the tracer is about to wrap is already a tracer. The net effect is of course double tracing. More importantly, it is chaining multiple continuations together.