Pipeline argument binding

Topics: Web Api
Nov 6, 2010 at 2:39 AM

On the processors pipeline, what is required for an output argument to bind to an input argument? The following two conditions must hold or only the first: the output type must be assignable to the input type and the names must be equals?

From my observation, it seems that both conditions must be true.

Thanks

Pedro Félix 

Coordinator
Nov 6, 2010 at 2:42 AM

Currently yes, the binding is on name and type. We have considered having a multi-level scheme which first checks on name and type, then checks on type only. Do you have a preference?

Looks like you are really digging through our API Pedro :-)

Nov 6, 2010 at 2:54 AM

For what I see, the name of an output argument is based on the name of the processor. This implies that we cannot have two processor classes producing the same output argument. This limits the replaceability of processors.

Regards

Pedro

Coordinator
Nov 6, 2010 at 7:35 AM

The names are not at all based on the name of the processor. I am not sure what you mean.

Nov 6, 2010 at 8:51 AM

When using the processor generic base classes (e.g. Processor<T, TOutput>), the output argument description is created by the ReflectionProcessorArgumentBuilder.BuildOutputArgumentCollection() method. This method uses the name of the processor type + "Result" to define the argument name.

If one derives directly from Processor, this behavior can be changed. However, deriving from one of the generic classes seems to be the common case, isn't it?

For instance, I created the following processor to extract the identity from the WCF context: PrincipalExtractorProcessor : Processor<HttpRequestMessage, HttpResponseMessage, IPrincipal> {...}

To use the extracted principal in the operation, the argument name must be PrincipalExtractorProcessorResult

Am I wrong here?

Pedro

Coordinator
Nov 6, 2010 at 10:18 AM

By default yes that is the name, however you can override the output name. Just set OutputArguments[0].Name to be the name you want and it will work. We've actually made this more explicit in the next drop as when you use strongly typed processors, you provide the name for the return value as a constructor param to the base processor.

Glenn

Coordinator
Nov 6, 2010 at 10:20 AM

For the input arguments the name is specified conventionally through the params in the Execute method. For example if you have ProcessorResult<int> Execute(string foo) {} then Foo in this case will used to match the input argument.

Cheers

Nov 6, 2010 at 2:29 PM

1) Defining the output argument name in the ctor seems a good solution to me. I like that!

2) How about processors with multiple outputs? Will there be any generic classes to simplify its development? Returning just one tuple with all the information isn't s solution, since the binding process will not be able to break the tuple apart and bind the elements individually.

3) For processors without side effects, it would be interesting to conditionally insert the processor in the pipeline only if its output is required.

For instance, consider the scenario of a processor that computes and outputs the roles of the user, and that this computation is costly (e.g.  external service access).

I would always register this processor. However, it would only be inserted in the pipeline if the operation required its output.

Thanks

Pedro

Coordinator
Nov 6, 2010 at 3:57 PM

1. Cool

2. You can support multiple outputs today, however in the strongly typed model you can have only a single output. If you have more outputs, you need to populate output arguments yourself, and then when you return your ProcessorResult override the return array.

3. I understand. We actually started off down the path of processors having a no-op state specifically for these scenarios. We thought it was weird throwing the processor in the pipeline if you know they are noop. With the processor configuration model, it's easy to write logic that deteremines if the processor should be added or not which is contextual to the operaiton. We also do support a form of no-op in that you can clear your processor output args programatically, and you can also return an empty ProcessorResult which has no value set. We'll continue to monitor usage of processors in the wild and customer feedback to see if we need such support. Do you think this is crticial?