views:

34

answers:

2

So I am learning WCF and I have run across an issue that I believe has to do with Instance Control/State but I am not sure.

Workflow is as follows, Basic client/server paradigm.

  1. The client calls a Method RetrieveBusinessObjects(criteria) and the server calls the datalayer and then puts them in an IList on the server side. It does not return this list to the calling Client.

  2. The client would then call a method say DisplayBusinessObjects() which would retrieve the IList from the Server, serialize them, bring them across the wire and display them.

If i try this using the WCFTestClient it works. If I run it from an actual client then I get back an BusinessObject[] of size 0. Which to me indicates I had no objects to return.

Is that a state mgmt issue or am I missing something?

+2  A: 

You need to consider this : by default, each call to a WCF service will result in a freshly created instance of your service class.

So if your first call to RetrieveBusinessObjects(.....) comes in, a new instance of the service class is instantiated, the items are retrieved and stored in the object instance - and when the call completes, the instance is disposed of.

Your second call to DisplayBusinessObjects() will again get a fresh instance of the service class - and it has no knowledge of the prior call, so it can't have anything in its BusinessObject array - it's a fresh instance, after all.

This kind of scenario doesn't work well - you need to re-architect your solution so that a single call will fetch and return the list of business objects - then cache them on the client. Or you need to use a persistent cache/store on the server to cache those items fetched in between calls.

marc_s
Well put! (15 chars)
Nate Bross
A: 

I agree with @marc_s, in that you should consider making your service operations more coarse grained, and consider combining them in a single operation. You don't indicate why your first call has to store the data in the service layer and only return it in the second call.

However, if you absolutely need this approach in your service implementation, then you can implement the service using per-session instancing:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IService
{
   private MyState _myState;

   public MyService()
   {
      _myState = new MyState();
   }

   public void RetrieveBusinessObjects(...)
   {
      _myState.Items = GetDataFromDataLayer();
   }

   public IList<Item> DisplayBusinessObjects()
   {
      return _myState.Items;
   }
}

This ensures that each client gets its own instance of the service, and it's internal state. This approach doesn't scale particularly well however, so you might need to look into that before deciding.

Tim Roberts