Apparently if you don't explicitly put an instancing mode on your service, what you get depends on the binding, and often times you're getting PerSession instancing, not PerCall as the docs indicate.
This morning I sat down and built a little example to verify this. I created a simple service with an instance variable constructed from a GUID. The contract allows you to retrieve the ID from the service instance:
[ServiceContract]
public interface IMyContract {
[OperationContract]
string GetId();
}
public class MyService : IMyContract {
string id = Guid.NewGuid().ToString();
public string GetId() {
return id;
}
}
I then exposed three endpoints from this service using three different standard bindings (without any binding adjustments): basicHttpBinding, wsHttpBinding, and netTcpBinding. My sample client then enumerated these endpoints making four calls to each endpoint using two proxies:
Console.WriteLine(endpointName);
Console.WriteLine(proxy1.GetId());
Console.WriteLine(proxy1.GetId());
Console.WriteLine(proxy2.GetId());
Console.WriteLine(proxy2.GetId());
Here are the results (notice that with basicHttpBinding, you do indeed get PerCall instancing, but with the other two, you get PerSession):
basic
161ebbd5-bd95-466b-b43d-2972fe815bb7
b8fc5ff9-669b-458f-b86f-598f9709d1b0
96f7bb42-b093-4930-9a1d-33d0599632cf
952ebd54-6501-4d10-8c16-7c51360ddfe7
ws
235cbdb3-b203-45a1-8807-60faeca97f95
235cbdb3-b203-45a1-8807-60faeca97f95
39b67030-94fa-4a28-852b-d1b4801b64ad
39b67030-94fa-4a28-852b-d1b4801b64ad
tcp
e2fbc193-587d-4c07-80be-73351d6adbc9
e2fbc193-587d-4c07-80be-73351d6adbc9
490d29bc-c08b-4375-b85f-402f0cb5122b
490d29bc-c08b-4375-b85f-402f0cb5122b
It's also interesting to note that if I query the service host's description:
host.Open();
Console.WriteLine(host.Description.Behaviors.Find().InstanceContextMode);
This prints out PerSession.
Just for kicks, I turned off security on all the bindings to see what would happen if there were no session. Now the results looked like this:
basic
8af37970-f315-426c-a4cb-5807f64eee50
20699967-7814-4b94-bec8-da3791788298
723bfe78-a968-41c2-b1f2-f2b1c3eec0bb
97837035-bef9-49ab-830a-151435951ac1
ws
468bafa5-baa6-4373-9118-dd74d138c73a
ef30ce05-bb9a-4225-81b8-18de433c6fc5
1c631970-6d85-4ccd-86c0-827466f67087
34d651b1-0643-474b-9a3a-3b623dc4fde6
tcp
16d17346-cc6c-40c1-8c36-13027dd62904
16d17346-cc6c-40c1-8c36-13027dd62904
53db2f9a-85e0-4834-8272-bc2673043784
53db2f9a-85e0-4834-8272-bc2673043784
As you can see, the only change is that wsHttpBinding is now using PerCall instead of PerSession, because that channel no longer supports sessions.
If I change my service definition to explicitly ask for PerCall, then I get PerCall instancing via all bindings, and the service description reports that the instance context mode is PerCall. Here's the attribute you put on the service type to control instancing:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService : IMyContract {
string id = Guid.NewGuid().ToString();
public string GetId() {
return id;
}
}
I think the safest bet is not to rely on the default, but to be explicit about your instancing mode. I'd love to hear from the WCF team whether they consider this a bug. One thing I can say for certain is that the documentation currently incorrect by saying PerCall is the default.
EDIT (10:36AM): Apparently PerSession is supposed to revert to PerCall if no session is available. So in short, it appears that the documentation is simply incorrect and that PerSession is the default, not PerCall. I still want to know if this is by design, though ;-)
Posted
Oct 13 2006, 08:24 AM
by
keith-brown