views:

90

answers:

1

I created a simple set of interfaces and a class that allow me to publish the additions and removals of items in a generic dictionary. Subscribers receive the entire list when they subscribe and after that, they get only the changes.

Although my solutions work, I am looking for something a little more standard, a little less home-grown. Do you have any suggestions?

Notes on what I've found so far:

I have been looking at Microsoft's Reactive Extensions (Rx). According to Jon Skeet's article "LINQ to Rx: second impressions" [1], he says "as soon as an observer subscribes, the observable publishes everything in the sequence to it (on a different thread, by default). Separate calls to Subscribe make the observable iterate over the sequence multiple times." This sounds like the basic idea, but I can't find any specific examples and I'm not really sure about the thread-safety of "Subject" or "AsyncSubject" yet.

Notes on my home-grown solution:

The structure that is delivered to subscribers looks like this:

/// <summary>
/// Interface for a set of changes that are being published.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TItem"></typeparam>
public interface IPublication<TKey, TItem>
{
    /// <summary>
    /// Version of the list.
    /// </summary>
    long Version { get; }
    /// <summary>
    /// Items that were added or updated.
    /// </summary>
    IEnumerable<TItem> ChangedItems { get; }
    /// <summary>
    /// Keys to items that were removed.
    /// </summary>
    IEnumerable<TKey> RemovedKeys { get; }
}

The subscribers themselves must implement this interface:

/// <summary>
/// Interface for a subscriber that will receive IPublication{TKey, TItem} deliveries from a publisher.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TItem"></typeparam>
public interface ISubscribe<TKey, TItem>
{
    void Deliver(IPublication<TKey, TItem> pub);
}

And of course my generic dictionary publisher class has this method:

/// <summary>
/// Adds the give subscriber to the list of subscribers and immediately publishes the
/// dictionary contents to the new subscriber. The return value may be disposed when
/// the subscriber wishes to terminate it's subscription.
/// </summary>
/// <param name="subscriber"></param>
/// <returns></returns>
public IDisposable Subscribe(ISubscribe<TKey, TItem> subscriber);

[1] http://msmvps.com/blogs/jon_skeet/archive/2010/01/19/linq-to-rx-second-impressions.aspx

+1  A: 

This is not really an answer but tedious to put into the comments so putting it here... Not sure why are you looking at a standard out of box solution when your custom solution is easy to build and will work? Events are the simplest (and standard) way of achieving publisher-subscriber model but they are not thread-safe and also suffer from tight coupling between subscriber and publisher. MS patterns & practice group had published WCF based pattern but I think that you are looking for a fast in-process kind of code. Similarly, many other standard publish-subscribe solutions will be targeting application integration (ESB). In case you didn't find any alternatives and decided to go with your custom solution then you mar refer this artcile that describes issues in implementing this design pattern.

VinayC
Thanks for your answer. I try not to reinvent the wheel if I don't have to. Maybe I will write a blog article about my implementation. Then, I am sure to get a ton of people telling me what's wrong with it!
wizlb
I'll give you the answer since your comment helped me. I put the code that I'm using here http://code.google.com/p/waynescode/source/browse/#svn/trunk/Wc.DotNetCode/Wc.Common/PubSub
wizlb