"RPC" vs. Messaging in WCF
I have been in many conversations recently, both online and in the real world, involving the debate around whether or not a distributed systems technology such as Indigo should offer what some people call an "RPC" programming model and/or a message-passing programming model.
Let me just clarify that the use of the term "RPC" in this context is, I think, misleading because most people understand RPC to refers to a particular technology implemnetation of the concept of RPC in some flavour of DCE RPC. What we're really talking about here is, in fact, the way in which we express how a caller requests a (potentially) remote service to perform an action and return results.
One camp says that if you're talking to a service, you should always explicitly form a message and use explicit message-passing infrastructure to send the message to the service and, optionally, to recieve the response. The following is an example of a potential implementation of such a mechanism (from the caller's perspective):
Channel chan = new ChannelFactory.CreateChannel(endpointAddress);
ActionInvocationMessage msg = new ActionInvocationMessage();
msg.Action = "SayHello";
msg.Parameters.Add(new StringParameter("Forename", "Rich"));
msg.Parameters.Add(new StringParameter("Surname", "Turner"));
Console.WriteLine(chan.SendMessageSync(msg, new SayHelloCallback(HandleResponse)));
The other camp aims to simplify the developer experience by reusing development constructs in wide use today that result in code such as the following:
HelloWorldProxy proxy = new HelloWorldProxy(endpointAddress);
Console.WriteLine(proxy.SayHello("Rich", "Turner"));
We deliberated over this issue for MONTHS when creating WCF. We went around and around arguing each position, mocking up code examples, we worked with focus groups both inside and eternally to Microsoft. We wrote demo apps and we gathered all the feedback.
And the result? There wasn't one! The two camps were deeply divided on this issue. So what did we do? We built both into the very core of WCF!
There are those who demand to explicitly craft and manage every single message interaction between caller and sevice and there are a variety of reasons for this. There are also those who do not need to do so and would rather leave it up to the infrastructure to marshal calls across whatever wire connects the caller and the required sevice(s). There are those who wish to asyncronously send messages and handle the response to those messages. There are those who want to ayncronously invoke actions on a service and asyncronously handle the responses to those invocations. There are those who want to send and receive messages in any order at any time via a duplex communications mechanism. There are those who wish to invoke methods on services and to asyncronously handle responses in any order. WCF supports all of these notions. There are many other needs that WCF also supports including securing messages, increasing the reliability of sending messages or invoking methods, providing rich session support, enabling two-phase-commit distributed transactions., etc.
Because WCF lets you achieve most goals by explicitly writing messaging code or by using the infrastructure to marshal your invocations, you get to choose which programming style best meets your needs, your schedules and the capabilities of your developers.
Now, there will be some from one camp or another who will be itching to hit the "Post a Reply" button to tell me that we shouldn't support both methods and that one or the other should be removed. However, both camps need to understand that WCF is a general-purpose foundation for building app-app, service-service communications and needs to provide as broad, deep and rich set of capabilities as we possibly can in order to meet the requirements of a hugely diverse community.
By providing as much flexibility in WCF as we have is a testament to the fact that we fully understand the perspectives of both camps and wish to provide as much value to each as possible. The WCF team understand a great deal about this space having built and delivered everything from RPC, DCOM, ES & COM+, System.Messaging & MSMQ, ASMX, WSE, Remoting, etc. We've learned a lot about what works and what doesn't - from many viewpoints - productivity, performance, reliability, architecture, scalability, availability, etc. We've made subtle changes to the way in which proxies are generated (by suffixing "Proxy" to the name of service proxy classes) so that we help increase the awareness of service consumers that they're not invoking methods on local objects, whilst not impeding developer productivity.
If you think we've got something wrong, then please send your working code samples to us via the Indigo newsgroup along with what you'd like the code to look like. We can't guarantee to make the changes requested, but we are keen to make sure that we're meetings your expectations.