Update: Title corrected.
A couple of months ago, I posted an item for the WSE 3.0 wish list. Here's another one...
While working on one of the tools that we are going to present in a week or so, I needed to do the following but unfortunately WSE 2.0 doesn't support it.
In WSE, a message is represented by the SoapEnvelope class. A MySoapEnvelope class, which is a subclass of SoapEnvelope, can still be used with the SoapSender.Send(SoapEnvelope) method... of course... I don't need to explain inheritance, right?
So, why would anyone want to specialise SoapEnvelope? Well, MySoapEnvelope could expose custom headers as typed properties or elements in the Body of the SOAP envelope as typed properties. Additionally, it could provide methods to aggregate functionality or to process the envelope in a custom way. The underlying SOAP envelope still remains the same however. So, where's the problem?
Well, when registering a SoapReceiver, its Receive(SoapEnvelope env) method is called upon arrival of a message. Now, while we can use instances of MySoapEnvelope for outgoing messages, we can't receive instances of it to represent the arriving messages. The WSE runtime generates a SoapEnvelope instance and as a result the instance given to Receive() cannot be upcast to MySoapEnvelope. Yes, I could have copied everything from one instance to another but that's an overhead that could be avoided.
When generating an instance of the SoapReceiver, there could be an option to give the type of the specialised SoapEnvelope we want WSE to generate:
MySoapReceiver receiver = new MySoapReceiver(epr, typeof(MySoapEnvelope));
So, in MySoapReceiver.Receiver(SoapEnvelope env) we can now do this:
MySoapEnvelope myEnvelope = (MySoapEnvelope)env;
Or, if WSE 3.0 is going to target .NET 2.0, the same could be implemented better with generics:
MySoapReceiver<MySoapEnvelope> receiver = new MySoapReceiver<MySoapEnvelope>(epr)
with
class SoapReceiver<T> where T is SoapEnvelope
{
public virtual void Receive(T env) {}
}
and
class MySoapReceiver<T> : SoapReceiver<T>
{
public override void Receive(T env) {}
}
I think the above should work. At least I hope you get the idea.