Category Archives: WCF

Beware of this WCF Serialization Pitfall

Ideally, one should avoid data contracts with complex graphs- especially with repeated references and definitely ones with circular references. Those can make your payload explode on serialization. With repeated references, you may run into an integrity issue on deserialization. With circular references, the serialization will enter a recursive loop and you will probably run into a stack overflow.

Seeing that in certain situations, this becomes unavoidable, WCF has a way that you can tell it to preserve object references during serialization. You do this by setting IsReference to true on the DataContract attribute that you use to decorate the composite type that is your data contract.

So, for example:

[DataContract(IsReference = true)]
public class MyContract
{
   [DataMember]
   public string Member1 { get; set; }
   ...
   ...
}

This solves the problem- however, since WCF achieves this by augmenting the WSDL- beware of this when you are exposing your service to third parties (especially ones that are not using WCF or perhaps not .NET at all) and interoperability is a concern. Without IsReference set to true, the WSDL snippet for the above would look something like:

<xs:complexType name="MyContract">
  <xs:sequence>
    <xs:element minOccurs="0" name="Member1" nillable="true" type="xs:string"/>
    ...
  </xs:sequence>
</xs:complexType>

With IsReference set to true, this is what it looks like:

<xs:complexType name="MyContract">
  <xs:sequence>
    <xs:element minOccurs="0" name="Member1" nillable="true" type="xs:string"/>
    ...
  </xs:sequence>
  <xs:attribute ref="ser:Id"/>
  <xs:attribute ref="ser:Ref"/>
</xs:complexType>

See those two lines that got added (i.e. “Id” and “Ref”)? That could very well cause some other party’s WSDL parser/proxy generator to choke. You have been warned.

An Easy Service Proxy Executor for WCF

If you have adopted service oriented architecture (SOA) and are using WCF as the hosting/communication mechanism for your internal services, chances are you are doing one of two things: you publish each service like any old WCF service and your other services which are consumers of said published service consume it through its WSDL; or you create shared libraries that include the contract information that both the service and its consumer reference. Both are somewhat cumbersome but can be managed. If all your services are internal, though, going the WSDL route is somewhat of an unnecessary overhead and is just a bit more unmanageable.

Now, if you decide to go the second route, but still stick to the more obvious interface that WCF provides to instantiate and call proxies (ClientBase and the like), that is a bit of a waste – since those classes were built with generated-code proxies in mind. In that case, the better option really is to have a mechanism to obtain a ServiceEndpoint and use that along with the contract information to create your own ChannelFactory – where you can then call CreateChannel to get your proxy. A lot less code and a lot more manageable.

To this end, for my own purposes, I built a bunch of classes that comprise my WCF service executor module. This is part of the Services namespace in the new Commons Library. Here are what a few of the key classes look like – you should be able to surmise how they can be used. The most common usage example would be:

var response = ServiceCallerFactory
   .Create<IMyContract>()
   .Call(x => x.MyOperation(request));

 

IServiceCaller

public interface IServiceCaller<out TChannel>
{
     void Call(Action<TChannel> action);
     TResult Call<TResult>(Func<TChannel, TResult> action);
}

ServiceCaller

public class ServiceCaller<TChannel> : IServiceCaller<TChannel>
{
      private readonly ServiceEndpoint endpoint;
      private readonly EndpointAddress endpointAddress;

      public ServiceCaller() {}

      public ServiceCaller(ServiceEndpoint endpoint)
       {
             this.endpoint = endpoint;
       }

      public ServiceCaller(EndpointAddress endpointAddress)
      {
             this.endpointAddress = endpointAddress;
      }

      public void Call(Action<TChannel> action)
      {
             var channelFactory = this.endpoint != null
                   ? new ChannelFactory<TChannel>(this.endpoint)
                   : new ChannelFactory<TChannel>();

            if (this.endpointAddress != null) channelFactory.Endpoint.Address = endpointAddress;

            var channel = channelFactory.CreateChannel();
             try
             {
                   action(channel);
             }
             catch
             {
                   channelFactory.Abort();
                   throw;
             }
             finally
             {
                   channelFactory.Close();
             }
       }

      public TResult Call<TResult>(Func<TChannel, TResult> action)
      {
             var channelFactory = this.endpoint != null
                   ? new ChannelFactory<TChannel>(this.endpoint)
                   : new ChannelFactory<TChannel>();

            var channel = channelFactory.CreateChannel();
             try
             {
                   return action(channel);
             }
             catch
             {
                   channelFactory.Abort();
                   throw;
             }
             finally
             {
                   channelFactory.Close();
             }
       }
}

ServiceCallerFactory

public static class ServiceCallerFactory
{
       private static readonly object serviceCallerMapLock = new object();

      private static readonly IDictionary<Type, ServiceCaller> serviceCallerMap = new Dictionary<Type, ServiceCaller>();

      public static Func<Type, ServiceEndpoint> ServiceEndpointAccessor { get; set; }

      public static IServiceCaller<TChannel> Create<TChannel>(EndpointAddress endpointAddress = null)
      {
             ServiceCaller caller;
             if (serviceCallerMap.TryGetValue(typeof (TChannel), out caller))
                   return (IServiceCaller<TChannel>) caller;

            lock (serviceCallerMapLock)
            {
                   if (serviceCallerMap.TryGetValue(typeof (TChannel), out caller))
                         return (IServiceCaller<TChannel>) caller;

                   if (ServiceEndpointAccessor != null)
                   {
                         var serviceEndpoint = ServiceEndpointAccessor(typeof (TChannel));
                         if (endpointAddress != null) serviceEndpoint.Address = endpointAddress;
                         caller = new ServiceCaller<TChannel>(serviceEndpoint);
                   }
                   else
                   {
                         caller = endpointAddress == null
                               ? new ServiceCaller<TChannel>()
                               : new ServiceCaller<TChannel>(endpointAddress); 
                   }

                  serviceCallerMap[typeof (TChannel)] = caller;
            }

            return (IServiceCaller<TChannel>) caller;
      }
}

RudyMQ: A rudimentary message queue for Windows

To skip to the source code, click here.

For some odd reason out of the blue, I got this hankering to build a message queue (albeit rudimentary – hence the name) from scratch. I’ve been working with MSMQ for a while now, mostly as a transport for WCF. As cool as it is, it can really get on your nerves at times. It is an enterprise grade product, after all, which means there are a lot of dials you can turn. If something is not right, you’ll get an error. If your experience has been the same as mine, you will recognize the dreaded insufficient resources error that MSMQ gives you for almost any of a thousand things that can go wrong.

That got me thinking that if in most cases, I don’t really need all the enterprise grade features of MSMQ, a simpler managed-code version may suffice. .NET gives you many varieties of queue or queue-type data structures that one could leverage and combine with something like WCF to build a message queue. The only serious issues you would have to deal with, I guess, would be concurrence and performance. The use of read-write locks greatly helped with both, although I foolishly did not keep a record of the performance test results around.

Anyway, you can find more details over here. Feedback appreciated as always. You can also find the source code here.

As I think back, I think it took me longer to get the WCF binding working than the actual message queue itself. If you think just using WCF is a chore, try building your own channels. The lack of available documentation online and how to get something like this working end-to-end was shocking. So, that – I believe – is another blog post in the works.