July 6, 2010

WCF facility for Castle Windsor - Client

Last blog post I talked about using the WCF facility to provide a us with a WCF service in a hosted environment. In this blog post I will show you how to three ways to use a WCF client inside your components, of course one being about using the WCF facility to provide you with a WCF client.

This post is part of a blog post series about the WCF facility. See the introduction post for the other blog posts.

Implementation 1

The first implementation is the easiest of the three. Just create a service reference and instantiate a WCF client from the generated code somewhere in code. This however create a tight coupling between the classes, so you can not swap a implementation and thus makes unit testing a lot more difficult. I can't recommend this way, so I don't have any more to say about this subject.

Implementation 2

The second implementation is a bit more work, but does provide you with more flexibility. In this solution you would still add a service reference. However instead of creating a WCF proxy yourself, you just let Castle Windsor (or any other DI container) inject a instantiation of the generated WCF client. This is possible since the generated classes include a interface. You can also override some parameters that the generated WCF proxy provides, such as the configuration name or the end point address. This will be more loosely coupled, since your code now depends on a interface being injected into the component instead of creating a WCF client itself. So unit testing is now more easy, since you can easily mock the interface and inject it in your components. However it still feels a bit wrong depending on the generated interface. Also using the async pattern is not possible using just the interface.

Implementation 3

The final implementation is using the WCF facility to provide you with a WCF proxy. This is mostly the same as implementation 2, this implementation however does not require adding a service reference. All you have to have is the interface to the service. You do have to add a few more things manually, but I find that to be a good thing. That way you know what is going on, instead of depending on a generated class with half a dozen constructors.

To get things starting, we first have to add the WCF facility to our Windsor Container. If you don't have the DLL's grab them from the demo project or compile your own from the source.

_container = new WindsorContainer().AddFacility<WcfFacility>();

Now you have to add the interface to your container using the Register method. Getting the interface might be a bit tricky, if you don't 'own' the service or it isn't implemented in WCF. You can solve this by using the command line tool "svcutil.exe <url here to wsdl>". This will generate a proxy class in the current directory. Now you can grab the interface (and possible DTO classes) it generated and place it inside your own solution.

Now for the registration of your WCF client. Instead of giving your component a implementation, you will have to use the ActAs method. You have to use the static method 'DefaultClientModel.On' to get started (there are other clients but I have never used those before). You have to give this method one parameter, a IWcfEndpoint. The static class WcfEndpoint gives you a few implementation. Now you can choose if you want to do the configuration the familiar WCF way or use the alternative way that the WCF facility provides.

First the familiar WCF configuration, all you have to do is use 'WcfEndpoint.FromConfiguration'. You just need to make sure that the name provided to that static method is the same as the WCF client name in the *.config. To configure your *.config I recommend using the WCF Service configuration editor, it's no fun doing it all by hand.
container.Register(Component
.For<IDateService>()
.ActAs(DefaultClientModel
.On(WcfEndpoint.FromConfiguration("DateService")))
.LifeStyle.Transient);


A alternative way to configure your WCF proxy is using WCF facility. You will still use DefaultClientModel.On, you will however have to use different methods on the WcfEndpoint class. First of you need to specify the bindings in the WcfEndpoint.BoundTo, such as BasicHttpBinding or NetTcpBinding. You can just use the default constructor of the bindings or use a different overload and/or change the properties to make the binding behave differently. Then we can chain the next method on the WcfEndpoint.BoundTo and add the address using the 'At' method.
container.Register(Component
.For<IDateService>()
.ActAs(DefaultClientModel
.On(WcfEndpoint.BoundTo(new BasicHttpBinding())
.At("http://localhost:3976/DateService.svc/basic")))
.LifeStyle.Transient);

Both configuration ways are pretty easy. In the demo project I have included both configuration methods, though the familiar WCF way is commented out.

As you can see it's pretty easy to use the WCF facility to provide you with a WCF client and it makes your code a lot more flexible. It is even possible to use the asyc pattern with the WCF facility, more about that over at the official Castle wiki.

Download project

kick it on DotNetKicks.com

1 comment:

  1. Hi, The project download doesn't seem to be working, any chance you can upload it again?

    ReplyDelete