DESKTOP

Implement an Observer (aka Subscriber) Pattern

10/13/2010 5:16:13 PM
While most notification systems use .Net events to communicate, there are times when you want something a little more decoupled. For this, .Net 4 provides two interfaces to aid in implementing this common design pattern.

Use the IObserver<T> and IObservable<T> interfaces.

The IObservable<T> interface is implemented on the class that provides data for others to consume.

class DataGenerator : IObservable<int>
{
private List<IObserver<int>> _observers = new List<IObserver<int>>();
private int _lastPrime = -1;

//inherited from IObservable<T>
public IDisposable Subscribe(IObserver<int> observer)
{
_observers.Add(observer);
observer.OnNext(_lastPrime);
return observer as IDisposable;
}

//notifies all subscribers of the new data
private void NotifyData(int n)
{
foreach (IObserver<int> observer in _observers)
{
observer.OnNext(n);
}
}

//notifies all subscribers that no more data is coming
private void NotifyComplete()
{
foreach (IObserver<int> observer in _observers)
{
observer.OnCompleted();
}
}

private static Random rand = new Random();

//let's just generate some aribtrary data
public void Run()
{
for (int i=0;i<100;++i)
{
int n = rand.Next(1, Int32.MaxValue);
if (IsPrime(n))
{
_lastPrime = n;
NotifyData(n);
}
}
NotifyComplete();
}

private static bool IsPrime(Int32 number)
{
//check for evenness
if (number % 2 == 0)
{
if (number == 2)
return true;
return false;
}
//don't need to check past the square root
Int32 max = (Int32)Math.Sqrt(number);
for (Int32 i = 3; i <= max; i += 2)
{
if ((number % i) == 0)
{
return false;
}
}
return true;
}
}


The IObserver<T> is implemented on classes that want to know about the updates in the IObservable<T>-derived classes.

class DataObserver : IObserver<int>
{
//give it a name so we can distinguish it in the output
private string _name = "Observer";
#region IObserver<int> Members

public void OnCompleted()
{
Console.WriteLine(_name + ":Completed");
}
public void OnError(Exception error)
{
Console.WriteLine(_name + ": Error");
}

public void OnNext(int value)
{
Console.WriteLine(_name + ":Generated data {0}", value);
}

#endregion

public DataObserver(string observerName)
{
_name = observerName;
}
}


To tie them together, merely subscribe the observers to the data generator:

DataGenerator generator = new DataGenerator();

DataObserver observer1 = new DataObserver("O1");
DataObserver observer2 = new DataObserver("O2");

generator.Subscribe(observer1);
generator.Subscribe(observer2);

generator.Run();

The output is something like this:

O1:Generated data -1
O2:Generated data -1
O1:Generated data 597759749
O2:Generated data 597759749
O1:Generated data 369128117
O2:Generated data 369128117
O1:Generated data 650236453
O2:Generated data 650236453
O1:Generated data 2143508953
O2:Generated data 2143508953
O1:Generated data 298906169
O2:Generated data 298906169
O1:Generated data 1296076711
O2:Generated data 1296076711
O1:Generated data 1970737339
O2:Generated data 1970737339
O1:Completed
O2:Completed
Press any key to exit...

Other  
  •  Use a Stopwatch to Profile Your Code
  •  Combine Multiple Events into a Single Event
  •  Internet Security and Acceleration Server 2004 : Additional Configuration Tasks
  •  Windows Server AppFabric
  •  Cloud Application Architectures : Privacy Design
  •  Cloud Application Architectures : Machine Image Design
  •  Windows Azure : Using the Storage Client Library
  •  Windows Azure : Using the Blob Storage API
  •  Windows Azure : Blobs - Usage Considerations
  •  Windows Azure : Understanding the Blob Service
  •  Design and Deploy High Availability for Exchange 2007 : Design Edge Transport and Unified Messaging High Availability
  •  Design and Deploy High Availability for Exchange 2007 : Design Hub Transport High Availability
  •  Design and Deploy High Availability for Exchange 2007 : Design CAS High Availability
  •  Design and Deploy High Availability for Exchange 2007 : Create Bookmark Create Note or Tag Implement Standby Continuous Replication (SCR)
  •  Windows Server 2008 : Utilize System Center VMM
  •  Windows Server 2008 : Create Virtual Hard Drives and Machines
  •  Windows Server 2008 : Manage Hyper-V Remotely
  •  Windows Server 2008 : Install the Hyper-V Role
  •  Windows 7 : Rolling Back to a Stable State with System Restore
  •  Windows 7 : Configuring System Protection Options
  •  
    Most View
    ADO.NET Programming : Microsoft SQL Server (part 3) - Using Stored Procedures with DataSet Objects
    Sony MDR-XB400 Extra Bass Headphones
    The Ubuntu Server Project (Part 4)
    New Products For May (Part 1)
    Flora - Nature - Photo Expert (Part 1)
    Which is the right router for you? (Part 1)
    Programming the Mobile Web : Server-Side Browser Detection and Content Delivery - Content Adaptation
    Introducing IBM WebSphere Enterprise Service Bus (WESB)
    HP Spectre XT 13 - Fashionably Sleek Design
    Panasonic Lumix DMC-GX1
    Top 10
    ADO.NET Programming : Microsoft SQL Server (part 4) - Working with Typed Data Sets
    ADO.NET Programming : Microsoft SQL Server (part 3) - Using Stored Procedures with DataSet Objects
    ADO.NET Programming : Microsoft SQL Server (part 2) - Using SQL Server Stored Procedures
    ADO.NET Programming : Microsoft SQL Server (part 1) - Connecting to SQL Server, Creating Command Objects
    Windows Phone 8 In-Depth Review (Part 6)
    Windows Phone 8 In-Depth Review (Part 5)
    Windows Phone 8 In-Depth Review (Part 4)
    Windows Phone 8 In-Depth Review (Part 3)
    Windows Phone 8 In-Depth Review (Part 2)
    Windows Phone 8 In-Depth Review (Part 1)