Search code examples
c#web-serviceswcfcastle-windsor

Castle Windsor & WCF Singleton lifestyle - could it be causing a bug?


I am working on a project involving financial transactions.

There can be any number of transactions coming in at the same time.

The problem is that, it seems as though, in a few cases, the transactions are being "mixed up", in an unpredictable way. I don't know if it's a result of our "bad" Lifestyle choices for Castle Windsor or there is other code causing it.

Would like to clear the air on Castle Windsor.

The logging shows that sometimes a particular request will be mixed up with a different response.

I know...Scares us too!

Main technology used is C# 4, Net 4.5, WCF, Castle Windsor

It is structured as follows:

  1. There are incoming transactions, so services should always be up
  2. There are 3 main services
  3. Service A - Singleton Lifestyle - instantiates a client to Service B using the ChannelFactory. Can spawn up to 3 threads. Note that container is of type Castle.Windsor.IWindsorContainer
container.Register(Component.For<IServiceA>().ImplementedBy<ServiceA>().LifestyleSingleton());
container.Register(Component.For<IServiceBFactory>().ImplementedBy<ServiceBFactory>().LifestyleSingleton());
  1. Service B - Singleton Lifestyle - uses a service reference, proxy client to Service C
container.Register(Component.For<IServiceB>().ImplementedBy<ServiceB>().LifestyleSingleton());
container.Register(Component.For<IServiceC>().ImplementedBy<ServiceCClient>().LifestyleSingleton());
  1. Service C - Singleton Lifestyle - connects externally to some API
container.Register(Component.For<IServiceC>().ImplementedBy<ServiceC>().LifestyleSingleton());

+-----------------------+              +-----------------------+                  +-----------------------+
|                       |              |                       |                  |                       |
|                       |              |                       |                  |                       |
| [WCF Service  A]      |              | [WCF Service  B]      |                  | [WCF Service  C]      |
| Instantiates a        +------------->+ Instantiates a        +----------------> | Connects to an external
| client to B using     |              | client to C using     |                  | RESTful API           |
| ChannelFactory        |              | a serivice referece   |                  | (Singleton Lifestyle) |
| (Singleton Lifestyle) |              | to C                  |                  |                       |
|                       |              | (Singleton Lifestyle) |                  |                       |
|                       |              |                       |                  |                       |
+-----------------------+              +-----------------------+                  +-----------------------+

Update 1

Now going through a related SO question, and in the mean time will try out all suggestions carefully


Solution

  • Your problem could be that you have single instances of each service being used from multiple threads, concurrently. Any instance level state, whether it be in your code or your service architectures' (such as a call context, for example) will be shared and edited by all calls to the service. As mentioned in the comments, a Transient lifestyle will help, but there are also lifestyles available specifically for WCF, such as PerWcfOperation.