I am a big fan of DRY coding, and I like to avoid boiler plate code as much as possible. Hence I have refactored all of my WCF channel faff into an AOP class, which deals with the lifecycle of the WCF channel.
I also am a big fan of async-await, especially with WCF, as it would in theory free up a thread that would normally be sleep-waiting for the response.
So I created an interceptor in the fluentAOP lib
private static object InvokeOnChannel(IMethodInvocation methodInvocation)
{
var proxy = _factory.CreateChannel();
var channel = (IChannel) proxy;
try
{
channel.Open();
var ret = methodInvocation.Method.Invoke(proxy, methodInvocation.Arguments);
channel.Close();
return ret;
}
catch (FaultException ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
catch(Exception)
{
channel.Abort();
throw;
}
}
However, when thinking a little about the solution I noted that in the case of a WCF contract of the form
[ServiceContract]
public interface IFoo
{
[OperationContract]
Task<int> GetInt();
}
GetInt would have unexpected results. Firstly the catch FaultException would do nothing. Secondly I would be closing the channel before the request returns. I could in theory switch to another code path if the return type is of Task. But I can't figure out how to await the results of a Task<> and then return an awaitable.
This of course is especially difficult since with runtime AOP I would not have access be able to use generics of the return type (without the whole bodge of reflection).
Any ideas how to implement this function as an awaitable, which closes the channel on complete and catches/marshals exceptions to the calling thread?