Wcf client proxies created by WCF and timeout

In this post, Alessandro explains how to create dynamically wcf proxy objects through Castle Windsor. We used this factory for some services exposed with basichttp binding with no problem, now we are using WS* binding and we are experiencing some problems.

The problem arise when the client spends too many time without calling the service. After a long inactivity when we try to call a service function we get an error. The reason can be seen here. Our structure is a MVC on winform, so the controller depends on IxxxService interface to communicate with the server. Now I need a way to intercept communication failures and recreate another proxy to start communication again, and I do not want to insert this code everywhere I call a service function.

I decided to modify the facility to support this scenario, here is the main function that build dynamically wcf proxy

public static object CreateWcfChannelProxy(Type service, string endpoint)
{
    var interceptor = new WcfProxyInterceptor(service, endpoint);
    object wcfProxy = InnerCreateProxy(service, endpoint, interceptor);
    Object wrapped = Generator.CreateInterfaceProxyWithTargetInterface(
        service, wcfProxy, interceptor);
    return wrapped;
}

The function InnerCreateProxy is the one described in original Alessanrdo’s post

internal static object InnerCreateProxy(Type service, string endpoint, WcfProxyInterceptor interceptor)
{
    Type channelFactoryBaseType = typeof(ChannelFactory<>);
    channelFactoryBaseType = channelFactoryBaseType.MakeGenericType(service);
    // Create an instance
    object instance = Activator.CreateInstance(channelFactoryBaseType, endpoint);
    if (!String.IsNullOrEmpty(UserName))
    {
        PropertyInfo gcpinfo = instance.GetType().GetProperty("Credentials", BindingFlags.Instance | BindingFlags.Public);
        ClientCredentials c = (ClientCredentials) gcpinfo.GetValue(instance, null);
        c.UserName.UserName = UserName;
        c.UserName.Password = Password;
    }
    
    MethodInfo createchannel = instance.GetType().GetMethod("CreateChannel", new Type[0]);

    interceptor.ActualWcfClientProxy = createchannel.Invoke(instance, null);
    interceptor.ChannelFactory = instance as IDisposable;
    return interceptor.ActualWcfClientProxy;
}

The interesting part is the WcfProxyProxyInterceptor class, a castle interceptor that is used in conjunction with Castle DynamicProxy to create a proxy of the WcfProxy :). If it seems weird to create a proxy of a proxy lets look at this schema.

image

The reason behind this structure is: WCF Proxy abstracts the call to the server with a channel, but if it becomes corrupted, as example when timeout occurs, we need to recreate another valid proxy to communicate with the server. The problem is that now I need to instruct all controllers to use the new proxy. If I use another proxy that wraps WCF proxy, I can simply return that proxy to the controller, and let it manage wcf proxy recreation in case of CommucationException. Let’s see how the WcfProxyInterceptor works

internal class WcfProxyInterceptor : IInterceptor
{

    public Type TargetType { get; set; }

    public String Endpoint { get; set; }

    public Object ActualWcfClientProxy { get; set; }

    public IDisposable ChannelFactory { get; set; }

    public WcfProxyInterceptor(Type targetType, string endpoint)
    {
        TargetType = targetType;
        Endpoint = endpoint;
    }

    #region IInterceptor Members

    public void Intercept(IInvocation invocation)
    {
        SetCurrentProxyAsTarget(invocation);
        try
        {
            invocation.Proceed();
        }
        catch (CommunicationException cex)
        {
            DisposeActualProxyAndRecreateOther();
            invocation.ReturnValue = invocation.MethodInvocationTarget.Invoke(ActualWcfClientProxy, invocation.Arguments);
        }
    }

    private void DisposeActualProxyAndRecreateOther()
    {
        try
        {
            //First step, dispose everything needs to be disposed.
            ChannelFactory.Dispose();
            ((IDisposable)ActualWcfClientProxy).Dispose();
        }
        catch (Exception) {}
        //Recreate another proxy.
        WcfProxyActivator.InnerCreateProxy(TargetType, Endpoint, this);
    }

    private void SetCurrentProxyAsTarget(IInvocation invocation)
    {
        IChangeProxyTarget changeTarget = invocation as IChangeProxyTarget;
        changeTarget.ChangeInvocationTarget(ActualWcfClientProxy);
    }

    #endregion
}

IT simply wraps the call to invocation proceed to intercept all CommunicationException exceptions. When an exception occurs, it simply disposes the actual WCF Proxy to avoid leak, then it creates another wcf proxy and stores it internally in the ActualWcfClientProxy. Finally it does a direct invocation with MethodInfo in the new object (this because we cannot call interceptor.Proceed() multiple times). The trick is in the function SetCurrentProxyAsTarget, that uses the IChangeProxyTarget interface to change the wrapped object for each call. With this situation the Controller can use the IXxxxService interface without worrying of communication exception and WCF proxy recreation. 

Alk.

Tags:

Manage Scope or Execution Context of Repository

In a project I’m working with Guardian, we are using NHibernate behind a Repository Pattern. Despite the question if is good or not good to shield the session behind a Repository,we encountered a classic problem.

The software is structured as service, we use Castle Nhibernate Facility and Wcf Integration Facility plus a simple interceptor that manages the concept of “Single session per service call”. Now we are developing some interface in WPF, and this program can dialogate directly with database, without the need to access the db through wcf service. Since we are using MVVM, we makes heavy use of binding, and we like to use lazy load, to keep the logic simple. Instead of returning Dto, a special service class is used to directly return NHibernate persistent object, and if the user want to browse some internal collection of this object we can simply bind the view to entity collection property, and the collection will be fetched when needed with lazy load. Since we have a tree structure this solution is really simple and works really well.

The problem arise because the repository use a single session per call, so when the ViewModel ask for an object, the service return a disconnected object.

image

This happens because the repository does not have control over the lifetime of the session, it simply open the session, does whatever he need to does with the session, and then Dispose it. Nhibernate Castle integration helps a lot because it keeps track of session reference counting, so if you open a session, and in the same CallContext you open another session, you get a sort of a “weak reference” to the original session. This means that the session gets disposed only when the first created session is disposed.

To use Lazy load in the ViewModel we could simply call ISessionManager.OpenSession() in the constructor of the ViewModel and dispose resulting session in ViewModel Dispose() function. This is not good because it violates repository encapsulation, because you must know how repository is implemented internally.

Moreover it is really ugly to see a nhibernate ISession created in the ViewModel, only to keep session alive, because it vanished all benefit of shielding the ISession behind a repository. A better solution is to create a class like this one.

public class RepositoryScope : IDisposable
{
    private ISessionManager SessionManager { get; set; }
    private ISession Session { get; set; }

    protected RepositoryScope(ISessionManager manager)
    {
        SessionManager = manager;
    }

    #region IDisposable Members

    public void Dispose()
    {
        ///close the most external scope
        Session.Dispose();
    }

    #endregion

    public static RepositoryScope BeginScope()
    {
        RepositoryScope scope = new RepositoryScope(
            IoC.Resolve<ISessionManager>());
        scope.Session = scope.SessionManager.OpenSession(
            ConfigurationRegistry.MainDatabaseConnectionName);
        return scope;
    }
}

This simple class does internally a simple task, it creates a session and dispose in Dispose() method. In this way if you call RepositoryScope.BeginScope() you are actually creating a ISEssion that will be disposed when you will call Dispose() on the RepositoryScope object.

With this simple class the repository remains unchanged, and the caller can manage the lifecycle of repository context, without the need to know his internal implementation.

Alk.

Tags: