C# 4.0, REST and the dynamic keyword

February 16th, 2009 | Tags:

I’ve been playing around with the CTP of Visual Studio 2010, and I really like the new dynamic keyword and the IDynamicObject interface.

I recently read nikhilk’s blog, and came across two articles titled More Fun with C# 4.0 – Dynamic REST Service Calls, and RESTful Live Search Service.

I would highly recommend these two articles, since they demonstrate very well the usefulness of the new dynamic keyword in C# 4.0. I was already tinkering with a similar solution, encapsulating WCF in much the same way nikhilk had done with RESTful services. The problem, however, is that it’s highly difficult to promote dynamic behavior over standardized WCF, due to the requirement of service-, and data contracts. You just can’t send random objects over the wire via WCF. They have to be marked with the attribute DataContact, all the way up the hierarchy.

One solution, would be to create a generic WCF service and accompanying client, that would acts as proxies, tunneling dynamic invocations over WCF.

Something along the lines of …

[ServiceContract]
public interface IGenericService
{
  [OperationContract]
  object Invoke(string method, object[] args);

  [OperationContract]
  object GetProp(string property);

  [OperationContract]
  void SetProp(string property, object value);
}

public class GenericService<T> : IGenericService
  where T : IDynamicObject, new()
{
  object IGenericService.Invoke(string method,
    object[] args);

  object IGenericService.GetProp(string property);

  void IGenericService.SetProp(string property,
    object value);
}

public class MyService : DynamicObjectBase
{
  [OperationContract]
  public void ServiceMethod1(string param1, int param2)
  {
    ...
  }

  ...

}

ServiceHost<GenericService<MyService>> service =
  new ServiceHost<GenericService<MyService>>();

...

dynamic client =
  new DynamicWCFClient("net.tcp://localhost:1000/MyService");
client.ServiceMethod1("Test", 42);

But this is far from optimal, since it would only work with services I’d write myself, and also negate much of the purpose of WCF and its reasons for being.

Preferably I would like only the client to be encapsulated by IDynamicObject, leaving the service alone, so that it works with any WCF service.

A better way, would instead be to dynamically download the service WDSL and generate a strongly typed client at run-time, which you then compile and return as an object reference, which you can then pass into a dynamic value.

Something like…

// Download WDSL
WDSLDownloader downloader = new WDSLDownloader(
 ConfigurationManager.AppSettings["ServiceMEXUri"]);

// Generate source code for a client class and compile it
...

// Create a new instance of the newly compiled client class
dynamic service = Activator.CreateInstance(clientType);

// Invoke some methods on it
service.Foo();
service.ServiceMethodOne();

This works, and it is seriously smooth. However, it does have an initial performance penalty and I don’t really like the idea of having to download the WDSL and generate the source code for the client class and compile it at run-time on-the-fly like this.

The best way, would be to write my own replacement for the ClientBase class that implements IDynamicObject, and simply generate WCF messages from those. This, however, requires a lot more low-level plumbing of WCF.

And that’s precisely what I’m going to do!

No comments yet.