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