OK, this does not happen too often, but I am copying here part of a thread and especially my answer from the MSDN WCF forums.
Without further ado, let's go...
-------
Hello All,
I'm looking for some design guidance about WCF.
I want to build an application where my business objects live in one process (the server). I want to be able to attach arbitrary UI’s (or interested parties) to this process to display information about the business objects, as well as manipulate them. These UI’s could live on the same machine, or on other machines.
I would like provide a uniform interface to these UI’s regardless of where they live (same machine or other machines). It seems like this is an ideal circumstance to use WCF (based on the whitepapers on WCF), but once I started playing with the June CTP I began to wonder if WCF would be the approach Microsoft had in mind for this situation.
For example, I would like the UI objects to subscribe to events from the business objects, so if one changes, they can be notified. But there doesn’t seem to be a natural way to do this with single call semantics, which seems to be what WCF encourages.
Indeed, I have concerns about single call semantics for this in general, since these business objects have lifetimes on the server. Also, WCF does not encourage handing out object references, and Session based services don’t really make sense either (since WCF creates the server side objects itself, rather than mapping them to any existing business objects).
I’m really looking for some guidance on what anyone (especially the developers at Microsoft) thinks about how WCF would fit with a situation like this. And if WCF isn’t the right approach, what technology/framework/approach would be best.
-------
For me it looks like WCF is quite a perfect fit. In addition to what you describe as 'single call semantics' - what I now would like to interpret as request/reply operations - WCF also offers other message exchange patterns (MEPs).
If you want to get notified by any arbitrary change in your service internals implementation, you can have the service interface implementation (in this case the WCF service) notify your consumers. This can be achieved by using an explicit duplex communication.
Let's take a look at a very simple duplex MEP, in this case it is from a small sample app I have built to illustrate various concepts of WCF, being duplex communication just one of it.
This sample enabled users to browse a technical video library, see their metadata and also the videos themselves and get notifications if new content is available. So I modelled the service contracts for this use case like this:
[ServiceContract(CallbackContract = typeof (ITecTvNotificationCallback))]
public interface ITecTvNotifications
{
/// <summary>
/// Subscribes for new episode.
/// </summary>
[OperationContract(IsOneWay=true)]
void SubscribeForNewEpisode();
}
[ServiceContract]
public interface ITecTvNotificationCallback
{
/// <summary>
/// Notification that a new episode is available.
/// </summary>
/// <param name="episode">The episode.</param>
[OperationContract(IsOneWay=true)]
void NewEpisodeAvailable(int episode);
}
In the service implementation we could just subscribe to any kind of event - e.g. one exposed by your business object - and then 'fire' the duplex callback into the client. Here, I chose to simply remember all of my subscribers for later reference:
public void SubscribeForNewEpisode()
{
ITecTvNotificationCallback caller =
OperationContext.Current.GetCallbackChannel<ITecTvNotificationCallback>();
if (caller != null)
{
if (dataNotifier == null)
{
dataNotifier = DataNotificationFactory.CreateInstance();
dataNotifier.RegisterSubscriber<TecTvService>(this);
}
if (!callers.Contains(caller))
callers.Add(caller);
}
}
As you can see, I have further decoupled the possible notification process inside the service itself. With a general publish/subscribe pattern (p/s) and a common implementation for it, I can literally register any kind of object and/or resource into this callback mechanism (in my case it is a simple change of a CSV file, but details do not matter if you follow this well-known p/s pattern).
Now, if any events occurs based on my p/s implementation, the OnNotification method from my general p/s framework gets invoked in my service. From there I just loop through my registered consumers and shoot them a notification message based on their callback contract:
public void OnNotification(DataChangedEventArgs e)
{
Action<ITecTvNotificationCallback> invoke =
delegate(ITecTvNotificationCallback callback)
{
callback.NewEpisodeAvailable(e.Episode);
};
try
{
callers.ForEach(invoke);
}
catch (CommunicationException)
{
// TODO: Log exception
}
}
Beware that if you are doing duplex and use an appropriate HTTP-based binding (like WsDualHttp), then you need an accessible back channel, as the HTTP-based duplex communication uses two HTTP connections. If you, however, choose a NetTcp binding the callback takes place on the same open TCP connection, but still you need to have all firewalls in between the parties configured correctly.