Operation Contract Overloading in WCF.. Not your usual Polymorphism!
There is no denying the fact that Microsoft has made life easy for Developers, both Windows and Web. Over the years MS have come up with great IDEs using which any High School Student could go ahead and build a fully functional application(Yes, it’s that easy).
Microsoft makes things easy for people by abstracting all the complexities of any technology or development environment. The underlying basics of any technology are abstracted into things like toolboxes and familiar syntax for a developer. BUT, sometimes the abstraction feels so real that we forget the very basic principles of the technology we are using.
Same holds true for WCF services. WCF services are actually web services with a lot of MS magic to make it look like any other OOP(Object Oriented Programming) technology. A lot of the magic can be credited to the familiar VS IDE and the C#/VB programming language.
Just because C#/VB(language used in WCF development) supports (function)Polymorphism, does not mean web services support it.
This is exactly what MS does to a lot of naive developers. Abstract all the intricacies and complexities of the real thing. Although this(the fact that web services do not support function polymorphism) may sound like “usual” to a lot of Web developers out there, BUT believe me, a whole lot of developers are not aware of this.
We’ll be discussing method overloading in WCF services here – Why it does not work and what options do we have.
Honestly, even I wasn’t aware of this fact a while ago, before a friend of mine (Rahul Verma) decided to enlighten me on this.
So, on to the issue. You build a WCF application in Visual Studio.
- You write out a Service Contract class say ServiceX.cs
- You write an Operation Contract say void DoWork();
- You write another Operation Contract say void DoWork(string message);
- Build the Project; the Project’s Build succeeds.
Now, As soon as you launch your WCF Web service (hitting something like http://localhost/ServiceX.svc) -> “BAM!!!” , you have an error message.
Server Error in ‘/’ Application.
Cannot have two operations in the same contract with the same name, methods DoWork and DoWork in type WcfServiceApp.IServiceX violate this rule. You can change the name of one of the operations by changing the method name or by using the Name property of OperationContractAttribute.
Well, as you can see the error message is Self Explanatory. What went wrong is that we assumed that Web services behave the same way as any Object Oriented language and that we could indeed overload methods in Web services.
The issue occurs when our IIS tries to get the metadata of the web service and generate the WSDL, at that point it throws an exception (for reasons stated above). MS might have had their own reasons for not putting compile time checks for this in WCF services(though it would be nice to have it).
Now, on to the solution and options available to us from here. But before that we need to get our head around 2 facts.
First, we need to accept the fact that method overloading is just a programming technique to make/keep our code manageable/maintainable. In some cases it also improves the readability of the code. BUT, its not something we cannot do without.
Second, there is absolutely no clean solution to get around this issue. You can never achieve/leverage the full benefits of method overloading in web services. That’s how the web is built.
Use the Name property of Operation Contract Attribute to differentiate the methods in WSDL.
[OperationContract(Name = “DoWork1“)]
[OperationContract(Name = “DoWork2“)]
Result: The web service will build fine and host successfully, BUT when you consume the web service in a Client, the method names in the intellisense will be DoWork1() and DoWork2(string message)
So, we have achieved overloading on the server, BUT while consuming the methods we still do not have same method names. We have to call different methods.
You can specify same name methods in different Service contracts. For e.g., you could have void DoWork() in IServiceX.cs and void DoWork(string message) in IServiceY.cs.
Result: The web service will build fine and host successfully, BUT when you’ll be consuming the web service, you’ll have to anyway instantiate different Client Channel/Proxys for IServiceX and IServiceY.
Hence, we still do not have proper method overloading .
Now, if you are hell bent on having method overloading available on the client consuming the WCF service we have a hack for that.
First, Implement Workaround #1 then You could actually tinker with the generated metadata classes (Reference.cs) and change the method names/attributes of the generated methods.
This way you’ll have proper overloaded methods in intellisense.
The downside of this method is the next time the proxy class is generated, you’ll loose your manual modifications. That’s the reason the method is not very practical.
So, going by the above observations, it seems futile to try to achieve method overloading in WCF web services. Its best to avoid it in web services as implementing it could involve a lot of effort and it does not seem to bring any real benefits to the bench.