Archive for July, 2010
WCF Service Proxies – Channel Factories
Some time ago I got a bit fed up with the standard way that Visual Studio creates WCF client proxies. I.e. right click and add service reference. Although it is fairly simple to create service clients this way, it generates a load of horrible code within you project. It also has the following short comings:
- It doesn’t offer compile time checking against the service contracts – i.e. if the service contract changes the compiler doesn’t tell you. this is of course the expected behaviour for 3rd party services but not really what you want for internal services.
- If you want to layer any extra code on top of your service clients, for example error handling or logging then you have to repeat this code for each service client using a mechanism such as partial classes.
Fortunately there is a better way to achieve this in the form of Channel Factories. If you have access to the assemblies containing the service contracts (this should be the case for internal services) then you can use channel factories to create the service proxy on the fly.
I have put together some infrastructure code for managing WCF client proxies (see attached Zip file at the bottom of the post).
This code also provides the following:
- Some code based default endpoints for Http and NamedPipes.
- Convention based approach to config.
- Wraps the WCF client with error handling to safely managed the faulted state.
The usage is a as follows:
Registering a WCF client proxy for an Http Endpoint.
IWindsorContainer container = new WindsorContainer(); container.Register.Component.For().ImplementedBy (). ImplementedBy ().LifeStyle.Transient); WindsorProxyHelper.RegisterDefaultProxyTypeOf (Container, "MyServiceAddress"); // Now resolve the proxy. IServiceProxy myServiceProxy = container.Resolve >();
Two things to note from the above code are:
- It assumes that you are using Windsor to resolve your service proxy, so make sure that all of the dependent objects are registered.
- Its assumes that you have added the appsetting “MyServiceAddress” in your config file. This should be the address of you service e.g. http://service.me.com/MyService.svc.
To use the proxy client use the following syntax:
// Now resolve the proxy. IServiceProxymyServiceProxy = container.Resolve >(); // Assuming the service has a method called "Calculate" which accepts an integer and returns a // decimal... decimal result; myServiceProxy.Use( s => result = s.Calulate(25));