WCF, WCF Security

WCF Duplex contract / Message broker endpoints, and GetHashCode()

While consulting a variety of WCF projects recently, I have found instances of some service implementations that use GetHashCode() on the callback channel objects, to be used in performing tasks like, maintaining a dictionary list of message notification subscribers, etc.

In typical Duplex channel scenarios this is not a problem at all - why? Because, you would not even need to depend on GetHashCode() on the callback - since you are speaking to that unique "service providing" client in the current callback channel.

So there is no need to work with its hash code, unless you are working with it on a Per session InstanceContextMode, where it will be useful to use the hash code.

But things are not that straight forward in the case when the endpoint contract is that of providing Message broker kind of services, where there are multiple potential clients that can subscribe to its services.

Although it is legitimate for service developers to get tempted and use GetHashCode() on callback channel clients (service providing clients), I have constantly recommended against that practice (particularly in the context of WCF endpoints that provide message broker service) for the simple reason that the hash code that the service gets from the callback channel implementers (i.e. the hash code of the InstanceContext objects that you get from the operation context in a duplex scenario) need not be unique, consequently ending up with either potential exceptions being thrown in your service code (for example by the Dictionary<Key, Value> Add () method), or the service ending up working with incorrect "service providing" callback endpoints (clients), thereby causing grief at run-time.

Specifically in a message broker service scenario, one might be tempted to think that the InstanceContext (i.e the service providing client) is unique, so there is nothing wrong in depending on the GetHashCode() call on it.
But the fact remains that,  the service callback implementations are neither asked to provide a custom overridden implementation of the GetHashCode() via the callback service contract, nor there is any guarantee that the InstanceContext (i.e. the servicing client) will provide one on its own.

So there is hardly any "uniqueness" reliability on the hash code that one gets from the callback service client.

Solutions that I keep recommending to my customers are: 

1. Don't rely on the GetHashCode() on the callback service client, but then let your service generate a unique ID/GUID for each of the callback client at the time of their Subscribe() requests on the service, and use it for the purposes like "look up" on the list for keeping a thread alive for a given callback instance, or unsubscribing it from the message notification list, etc.

2. If callback client is also written by the service developer, then provide an overridden implementation of the GetHashCode() in your callback.

One other thing that would come to mind is that you could also require as part of the callback contract that the implementer will provide a custom hash code.

That said, I would not recommend this option at all, since it brings in an implementation technicality specific detail (a non-business domain requirement/details) into the callback contracts, which is very ugly.
Also there is no guarantee that the callback InstanceContext will indeed provide a custom implementation (what if it returned the base implementation?).

Like i said, the best bet is of course, if callback client development is also in your control, then you are better off to write your own overridden implementation for GetHashCode() in your service callback contract implementation.

Enjoy safe WCF coding! :-)

- Sundar