I've been wanting a simplified WCF plugin architecture for .NET Windows service with easy debug console mode to make my life easier. Building services with Windows Communication Foundation (WCF) is simple and hard. The service and data contract code is simple, like this:
namespace Test2Common { [ServiceContract] public interface IMyOtherService { [OperationContract, FaultContract(typeof(WcfServiceFault))] string GetName(string seed); [OperationContract, FaultContract(typeof(WcfServiceFault))] Person GetPerson(int id); } [DataContract] public class Person { [DataMember] public string Name { get; set; } [DataMember] public string Title { get; set; } } }
But that is where simple ends. The hosting and client proxy code and the configuration XML (or code) is not simple. Even when I use tools to generate these artifacts, I find myself having to tweak and fix and delve deeper than time permits. And since I prefer simple, I decided to create a reusable framework for hosting my limited scope services. Here's what I wanted (download PluggableWcfServiceHost.zip (38.05 KB)):
Here's the simplified config with two services configured:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="wcfServices" type="WcfServiceCommon.WcfServiceConfigurationSection, WcfServiceCommon" /> </configSections> <appSettings/> <connectionStrings/> <wcfServices consoleMode="On"> <services> <add key="test1" serviceAddressPort="localhost:2981" endpointName="Test1EndPoint" authorizedGroups="WcfServiceClients,someOtherGoup" hostType="Test1Service.ThatOneService, Test1Service" contractType="Test1Common.IThatOneService, Test1Common" /> <add key="test2" serviceAddressPort="localhost:2981" endpointName="Test2EndPoint" authorizedGroups="WcfServiceClients,someOtherGoup" hostType="Test2Service.MyOtherService, Test2Service" contractType="Test2Common.IMyOtherService, Test2Common" /> </services> </wcfServices> </configuration>
And here's the implementation of the service (It really is simple):
namespace Test2Service { public class MyOtherService : WcfServiceBase, IMyOtherService { public string GetName(string seed) { base.Authorize(); return "This is my name: " + seed.ToUpper(); } public Person GetPerson(int id) { base.Authorize(); return new Person { Name = "Donald Trumpet", Title = "King of the Hill" }; } } }
Now for the really fun part. The client. Hey, where's the proxy? Hidden away just like it ought to be.
namespace WcfSvcTest { class Program { static void Main(string[] args) { using (var client1 = WcfServiceClient<IThatOneService>.Create("test1")) { Console.WriteLine(client1.Instance.GetName("seed")); var add = client1.Instance.GetAddress(8); Console.WriteLine("{0}", add.City); } using (var client2 = WcfServiceClient<IMyOtherService>.Create("test2")) { try { Console.WriteLine(client2.Instance.GetName("newseed")); var per = client2.Instance.GetPerson(7); Console.WriteLine("{0}, {1}", per.Name, per.Title); } catch (FaultException<WcfServiceFault> fault) { Console.WriteLine(fault.ToString()); } catch (Exception e) //handles exceptions not in wcf communication { Console.WriteLine(e.ToString()); } } Console.ReadLine(); } } }
To save space, I only wrapped the use of the client in try catch on the second test service.
Note: You have to remember that the WcfServiceHost requires the "common" and the "service" assemblies of your dynamically loaded services in it's bin folder. The client (see WcfSvcTest project in the solution) will also need a copy of the "common" assemblies in it's bin folder. You'll find I'm doing that for the test using post-build commands (copy $(TargetPath) $(SolutionDir)WcfServiceHost\bin\debug\). And of course, both need to have identical config sections as shown in the code.
I hope you find this WCF plugin architecture and the accompanying code useful. I will certainly be using it. If you do use it, please let me know how it goes.
Download PluggableWcfServiceHost.zip (38.05 KB)
Page rendered at Tuesday, February 07, 2012 6:22:42 AM (Mountain Standard Time, UTC-07:00)
DisclaimerThe opinions expressed herein are just that, opinions. Don't have a fit if you think they're wrong. Post your comment or write your own blog.