Why does a message encoder have to be specified before the transport when constructing a binding?
A message encoder doesn’t directly fit into a channel stack because the message encoder type doesn’t implement any of the channel shapes. Instead, a message encoder is an auxilliary piece used by one of the channels in the channel stack.
When a channel stack is constructed from a binding, the message encoder binding element therefore doesn’t actually build anything. During the message encoder binding element’s time to build, the binding element saves a copy of itself to the BindingContext in the BindingParameters collection. Later on, when a transport binding element is encountered, the transport may decide to search through the binding parameters to find the deferred messag encoder. It’s the transport that builds the message encoder rather than the binding itself.
That’s also why the message encoder has to be specified before the transport. If the transport binding element is encountered before the message encoder binding element, then the transport just has to assume that the binding doesn’t contain a message encoder. Most transports use a default message encoder if you don’t specify one in the binding so the build process continues for a while longer. However, if you’ve stacked the binding elements out of order, then the message encoder binding element will still be in the binding context at the end of the build process, from which you can infer that one of the binding elements wasn’t handled correctly.