What I want for asynchronous WCF clients and C#5 async/await
I have a problem with Adding a Service Reference (and thus using svcutil). It generates proxy interfaces and proxy datatypes. If my WCF service used custom datatypes, the service reference would create a proxy datatype for it. This gives me headaches because I think I have a type Foo when in fact I have a proxied version. Now I have to cast between them. Also, if I have added two service references and they used the same datatype, guess what? It will generate two different proxied datatypes. And if I change anything about the service or the datatypes, I need to regenerate the service reference. What a pain.
Instead, I do something like this:
[ServiceContract]
public interface IContract
{
[OperationContract]
int Add(int a, int b);
}
public class MyClient : ClientBase<IContract>, IContract
{
public int Add(int a, int b) { return base.Channel.Add(a, b); }
}
Nice and clean huh? The WCF client uses the same interface and same datatypes as the service so no need to regenerate service references. It's tightly coupled and I also get compile time errors if I change the service interface. The only problem is that doing it this way does not generate asynchronous client methods.
The Visual Studio Async CTP gives a sneak preview into the future of the language. It adds two new keywords async and await which make it dead simple to convert regular code into asychronous code. I won't go into detail on how it works, but in addition to the language/compiler changes it also includes a bunch of extension methods that add this new style of asynchronous access to a bunch of preexisting classes that have asynchronous methods. For example, TextWriter contains a synchronous Write() as well as the asynchronous BeginWrite() and EndWrite(). This CTP adds WriteAsync() which wraps the BeginWrite() and EndWrite() into this new async/await syntax. What I envision, and what I hope happens is that they also do some work on WCF client generation (hopefully not using svcutil, but extending ClientBase). I want there to be something like this:
[ServiceContract]
public interface IContract
{
[OperationContract]
int Add(int a, int b);
}
public class MyAsyncClient : AsyncClientBase<IContract>, IAsyncContract<IContract>
{
public async Task<int> AddAsync(int a, int b) { return await base.AsyncChannel.AddAsync(a, b); }
}
That's my pipe dream. I want to not have to generate proxy interfaces and datatypes, retain compile time errors when the interface changes, and not use svcutil. The IAsyncContract<T> would be enforced to take an interface that is marked as a ServiceContract. It would then take all the methods in the interface marked as an OperationContract and create a new interface with them, but changing their return types from what they were originally (e.g. int, string, List<double>, etc) to async Tasks (e.g. Task<int>, Task<string>, Task<List<double>>).
Right now I think it's impossible for an interface like IAsyncContract to exist and do what I would like, but maybe some kind of autogenerated code could take place on compile could net similar results. Thoughts?
