I had half an hour to fill while I waited for a large download, on my slow connection. I’d thought about re-implementing my C# WCF test host in F#. It didn’t look too complex, and indeed it wasn’t:
#light
#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\"
#r "System.ServiceModel.dll"
#r "Server.dll"
open System
open System.ServiceModel
open System.Diagnostics
open Coyote.FSWCFTest
let services = [ (typeof<TestWebService>, "http://localhost:8080/Test/FSWCFTest.svc") ]
let logException (msg, exn:Exception) =
Trace.TraceWarning(msg)
Trace.WriteLine(exn.Message)
Trace.WriteLine(exn.Source)
let startHost (serviceType:Type, url) =
try
let uri = [| new Uri(url) |]
let host = new ServiceHost(serviceType, uri)
host.Open()
Some(host)
with
| e -> logException ("Exception thrown starting service.", e)
None
let stopHost (host: ServiceHost option) =
try
match host with
| None -> ()
| Some(host) ->
if host.State <> CommunicationState.Closed then
host.Close()
Trace.WriteLine("Service Stopped")
with
| e -> logException ("Exception thrown stopping service.", e)
let showHostStatus (host: ServiceHost option) =
match host with
| Some(hst) ->
let strdots = new String ( '.', 40 - hst.Description.Name.Length);
Console.ForegroundColor <- match hst.State with
| CommunicationState.Opened -> ConsoleColor.Green
| _ -> ConsoleColor.Red
Console.WriteLine("{0} service{1}{2}", hst.Description.Name, strdots, hst.State.ToString())
| None -> Console.ForegroundColor <- ConsoleColor.Red
Console.WriteLine("Service failed to start.")
let main =
Console.Title <- "Server Test Console"
Console.BackgroundColor <- ConsoleColor.DarkBlue
Console.WindowWidth <- 120
Console.Clear()
Console.WriteLine("Server Test Console")
Console.WriteLine("Copyright 2008 Coyote Software, GmbH.")
Console.WriteLine()
let hosts = services |> List.map startHost
let mutable quit = false
while not quit do
let inp = Console.ReadLine()
let inpClean = inp.Trim().ToLower()
match inpClean with
| "exit" -> quit <- true
| "cls" -> Console.Clear()
| "status" -> let cc = Console.ForegroundColor
Console.WriteLine("Status at {0} is", DateTime.Now)
hosts |> List.iter showHostStatus
Console.ForegroundColor <- cc
| "stop" -> hosts |> List.iter stopHost
| _ -> Console.WriteLine("Unknown command {0}", inp)
done
This implementation is about half the size of the C# implementation, although the original has a couple of extra commands. I preferred Console.WriteLine to printfn, as I have used other Console methods, and I think the code is a little clearer.
One improvement to this app would be to have is use reflection to automatically find all the services in the assembly (rather than require the list to be set up), but I’ve been using the C# version almost daily for over a year, and its good enough like this.