My recipe for WCF part 2 – Using Castle Windsor to set up the connections

Download the code for this post here.

In my first post on WCF, I mentioned that I might implement a fast primality test around which I would build WCF services. Well, I tried, but in fact I’ve implemented a test which, whilst being fast from a theoretical computer scientist’s point of view, is really, really slow from anyone else’s. It took a week to test all the integers up to 100,000 on my newish, development-grade office desktop. It’s the Agrawal–Kayal–Saxena primality test, which, when it was published in this paper in 2002, was the first ever general deterministic primality test which was guaranteed to run in polynomial time. (Polynomial time, by the way, seems to mean polynomial in the logarithm of a number when it comes to primality testing or factoring. Go figure.) I was helped in my implementation of this by reading at least half of this friendly paper by Andrew Granville, and my implementation was of a version of the algorithm which incorporated the improvements I read about in this paper by Robert G. Salembier and Paul Southerington.

In theory, I think my implementation would test the primality of N where N is up to around 2^(2^20). The limit is imposed by the fact that I’ve used an array indexed by an 64-bit integer to hold the coefficients of polynomials whose degree can be as large as (lg N)^3 (where lg is the base 2 logarithm of its argument.) In practice, however, it took so long to test 2^31-1 (a Mersenne prime) that I gave up. I may set this test running on a computer which, unlike my laptop, doesn’t automatically shut itself down after a period of what it naively assumes to be inactivity.

But that’s enough amateur maths and computer science. Let’s get down to the programming.

The point is that Castle Windsor makes it extremely easy to use WCF, particularly on the client side. All you need to do to create strongly-typed proxy objects on your client side is

  1. Add the WcfFacility to your Windsor Container.
  2. Create a binding in your config file.
  3. Register all your services in the Windsor container, referencing the name of the binding in your config file and the URL of the service.

Here is the source code for setting up the IoC (here done in the Configure class of a Caliburn.Micro Bootstrapper class, because I’ve used Caliburn.Micro as a window driver):

protected override void Configure()

        {

            _container = new WindsorContainer();

            _container.AddFacility<WcfFacility>();

            _container.Register(

                Component.For<IWindowManager>()

                        .ImplementedBy<WindowManager>().LifestyleSingleton(),

                Component.For<IEventAggregator>()

                        .ImplementedBy<EventAggregator>().LifestyleSingleton(),

                Component.For<IShell>()

                        .ImplementedBy<MainWindowViewModel>().LifestyleSingleton(),

                Component.For<IHcfService>()

                        .AsWcfClient(new DefaultClientModel(WcfEndpoint.

                                BoundTo(new BasicHttpBinding(“defaultBinding”))

                        .At(http://localhost:1274/Hcfservice.svc))),

                Component.For<IPrimeTester>()

                        .AsWcfClient(new DefaultClientModel(WcfEndpoint.

                                BoundTo(new BasicHttpBinding(“defaultBinding”))

                        .At(http://localhost:1274/PrimeTester.svc)))

                );

        }

And here is the source code of the config file:

<?xml version=1.0 encoding=utf-8 ?>

<configuration>

    <startup

        <supportedRuntime version=v4.0 sku=.NETFramework,Version=v4.5 />

    </startup>

<system.serviceModel>

  <bindings>

    <basicHttpBinding>

      <binding name=defaultBinding/>

    </basicHttpBinding>

  </bindings>

</system.serviceModel>

</configuration>

 Not a ChannelFactory in sight. Lovely.

On the server side, you need to edit the markup in your .svc files to use the Castle Windsor factory:

<%@ ServiceHost Language=”C#” Debug=”true” Service=”PrimeTester     Factory=”Castle.Facilities.WcfIntegration.DefaultServiceHostFactory” %>

And finally you need to register your services, and all their dependencies, in the container. Here’s the global.asax class:

    public class Global : System.Web.HttpApplication
    {

        private WindsorContainer _container;

        protected void Application_Start(object sender, EventArgs e)
        {

            _container = new WindsorContainer();
            _container.AddFacility<WcfFacility>();
            // Register WCF services
            _container.Register(Component.For<IHcfService>()
                                         .ImplementedBy<HcfService>()
                                         .Named("HcfService")
                                         .LifestylePerWcfOperation());
            _container.Register(Component.For<IPrimeTester>()
                                         .ImplementedBy<PrimeTester>()
                                         .Named("PrimeTester")
                                         .LifestylePerWcfOperation());
            // Register all other classes.
            _container.Register(Classes
                                .FromAssemblyNamed("CalculatorServiceImplementation")
                                .InNamespace("CalculatorServiceImplemtation")
                                .WithService
                                .DefaultInterfaces()
                                .LifestylePerWcfOperation());

        } 
    }

So the take-home message is that I would strongly recommend you use Castle Windsor or another IoC which supports this sort of automatic creation of client proxies and makes a WCF class feel like any other dependency. But don’t worry if you’re using an IoC which doesn’t have this sort of feature, because it’s not that difficult to write it yourself, and I’ll demonstrate this in the next post on this subject.

The source code provides a very basic UI for inputting a number and determining whether it’s prime.

PrimeTester

Note that the sample code doesn’t cope very well with failure. (A quick and easy exmple is to put ‘2’ in to test.) Exception handling across a WCF process boundary sounds like good material for a later post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s