F# is Changing My Style


Tonight, I was writing some code that made use of transactional WCF bindings. I wanted to do some experimentation with all the bindings available to see which ones support flowing transactions. The pre-built bindings that do this will create a TransactionFlowBindingElement when you ask them to call CreateBindingElements(). The types I’m interested are concrete (no abstract methods) and have a zero-argument constructor. A few years ago, I would have done a bunch of looping constructs to look at each element. However, I’ve been doing a lot more work with F#. While doing this experiment in C# for a project, I wound up writing the following instead:

 

static void Main(string[] args)
{
    var bindings = from bindingType in typeof (MessageContractAttribute).
                       Assembly.GetTypes()
                   where typeof (Binding).IsAssignableFrom(bindingType) &&
                   !bindingType.IsAbstract &&
                   (from constructorInfo in bindingType.GetConstructors()
                           where constructorInfo.GetParameters().Length == 0
                           select constructorInfo).Count() > 0
                   select bindingType;

    var txBindings = from bindingType in bindings
                     where
                         (from bindingElement in
                              ((Binding) Activator.CreateInstance(
                                bindingType)).CreateBindingElements()
                          where bindingElement.GetType() ==
                            typeof (TransactionFlowBindingElement)
                          select bindingElement).Count() > 0
                     select bindingType;
    foreach (var txBinding in txBindings)
        Console.WriteLine(txBinding.FullName);
}

I would’ve loved a Seq.iter for the last 2 lines of the function. I think this is a good reason to learn F# or another functional language. It’ll change how you write code elsewhere. I’m not saying that this code is more readable, but it is interesting.

So, what does the code write out as the transaction supporting bindings?

System.ServiceModel.NetTcpBinding

System.ServiceModel.NetTcpContextBinding

System.ServiceModel.WSHttpBinding

System.ServiceModel.WSHttpContextBinding

System.ServiceModel.NetNamedPipeBinding

System.ServiceModel.WSFederationHttpBinding

System.ServiceModel.WS2007FederationHttpBinding

System.ServiceModel.WS2007HttpBinding

System.ServiceModel.WSDualHttpBinding

%d bloggers like this: