automatic Async calls in WCF

29 views
Skip to first unread message

Krzysztof Koźmic

unread,
Oct 15, 2008, 4:49:07 PM10/15/08
to Castle Project Development List
Hey, I want to get your opinions on idea I am playing with.
Basically, I want to do this: http://ayende.com/Blog/archive/2008/03/29/WCF-Async-without-proxies.aspx
but without having to write IAsyncBus but rather have it created by
the container for me.
for the sake of example let's just say that IBus has one simple method
void DoSomething(string param);

here's how I see it done.

When on the client I do kernel.Resolve<IBus>(), Windsor would return
to me mixin of the following:
1. IBusWithAsyncVersion created via new
ChannelFactory<IBusWithAsyncVersion>().CreateChannel();
2. IBusWithAsyncVersion would be a generated type that inherits from
both IBus and autogenerated at runtime IAsyncBus which would implement
AsyncPattern for IBus
3. Implementation of universal interface used to call IAsyncBus
methods, using IBus interface

number 3. would look something like this:


/// <summary>
/// Used to perform asyncronous calls on WCF service proxy
/// </summary>
/// <typeparam name="TContract">The type of the contract.</
typeparam>
public interface IAsyncClient<TContract> where TContract : class
{
/// <summary>
/// Begins the asyncronous call of a method designated by
<paramref name="call"/>. This is a version for methods returning some
value (methods that have return type other than void).
/// </summary>
/// <typeparam name="TResult">The type of the result.</
typeparam>
/// <param name="call">Expression calling syncronous version
of desired method, like 'c => c.MyMethod("Joe", GetAge())'</param>
/// <param name="callback">The callback method that will be
called when asyncronous operation ends. It's second parameter would be
the same method as method poined to by the delegate returned in
<paramref name="endCall"/></param>
/// <param name="asyncState">Optional parameter to be passed
to asyncronous call.</param>
/// <param name="endCall">The delegate pointing to a
counterpart End'operation' method. The same delegate will be passed as
the second parameter to the <paramref name="callback"/> method.</
param>
/// <returns></returns>
IAsyncResult BeginCall<TResult>(Expression<Func<TContract,
TResult>> call,
Action<IAsyncResult,
Func<IAsyncResult, TResult>> callback, object asyncState,
out Func<IAsyncResult,
TResult> endCall);

/// <summary>
/// Begins the asyncronous call of a method designated by
<paramref name="call"/>. This is a version for methods returning void.
/// </summary>
/// <param name="call">Expression calling syncronous version
of desired method, like 'c => c.MyMethod("Joe", GetAge())'</param>
/// <param name="callback">The callback method that will be
called when asyncronous operation ends. It's second parameter would be
the same method as method poined to by the delegate returned in
<paramref name="endCall"/></param>
/// <param name="asyncState">Optional parameter to be passed
to asyncronous call.</param>
/// <param name="endCall">The delegate pointing to a
counterpart End'operation' method. The same delegate will be passed as
the second parameter to the <paramref name="callback"/> method.</
param>
/// <returns></returns>
IAsyncResult BeginCall(Expression<Action<TContract>> call,
Action<IAsyncResult, Action<IAsyncResult>> callback,
object asyncState, out Action endCall);
}


and using it would look like this:

var bus = kernel.Resolve<IBus>();
var asyncBus = bus as IAsyncClient<IBus>;
string myParam = "a param";
Action<IAsyncResult> endCall;
asyncBus.BeginCall(b=>b.DoSomething(myParam),(ar,ec)=> ec(ar),null,out
endCall);

I am still woring on a prototype, but I wanted to get some feedback.
How do you like the idea? Would you change the IAsyncClient? How and
why?
Reply all
Reply to author
Forward
0 new messages