Friday, May 8, 2009

Using WCF and Spring.NET to Scale Your Architecture

Windows Communication Foundation (WCF) is more than just web services. Most of the .NET developers think of it as a replacement for old ASMX web services. Today I am going to show you how I am going use it in a different way. I am going to use it to distribute different components of a system to be run separately on different machines without re-compilation of your code. You can do this based on your needs and the hardware available.

First, Let us define the problem we are trying to solve. Assume that you are working on an application that part of its logic is to compute a complex operation. This operation can not be simplified and it consumes most of the application time. Your default deployment will be as following:


This deployment model will introduce a bottleneck to your application. What I have in mind is to deploy the application on a server and the complex component on another one. This way you can distribute the processing across your servers. Then the deployment will be as following:


Let us see a simple example for the implementation of the following components. This our service contract:

[ServiceContract]

public interface ICalcEngine

{

        [OperationContract]


        Operation CalculateOperation(Operation operation);

}

We will use spring to load your component hosted in memory as mentioned in the first deployment model.

      <object name="CalcEngineWCF.ICalcEngine"

              type="CalcEngineWCF.CalcEngine, CalcEngineWCF"/>

My proposed solution will allow you change the deployment model without changing a line of code in your application as mentioned in the second deployment model. You will deploy your complex component as a service on a remote host. In this case spring configuration in the client side (the main application server) will be as following:

      <object name="CalcEngineWCF.CalcEngineFactory"

              type="CalcEngineWCF.CalcEngineFactory, CalcEngineWCF">

        <property name="Address" value="http://remote-server:8000/CalcEngine/Service"/>

      </object>


      <object name="CalcEngineWCF.ICalcEngine"

                        type="CalcEngineWCF.CalcEngine, CalcEngineWCF"

                        factory-method="CreateWCFInstance"

                        factory-object="CalcEngineWCF.CalcEngineFactory"/>

I hope this will be clear enough for you to be able to apply this model in your applications.

You can also refer to a working example here. The mentioned solution contains 3 projects:

  1. CalcEngineWCF: Our complex component that needs to be distributed.
  2. WCFHost: Remote application that will host CalcEngineWCF.
  3. WCFClient: The main application server. Its name might be confusing because it acts as a client to the remote host.