Created
December 13, 2011 02:24
-
-
Save rbwestmoreland/1470171 to your computer and use it in GitHub Desktop.
Properly Implementing the Observer Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
/// <summary> | |
/// An example Observer pattern. | |
/// <para>The Observer pattern is a behavioral | |
/// pattern, whose purpose is to define a one-to-many | |
/// dependency between objects where a state change | |
/// in one object results with all its dependents | |
/// being notified and updated automatically.</para> | |
/// </summary> | |
public class Observer : IDisposable | |
{ | |
#region Property(s) | |
/// <summary> | |
/// Keep track of items you subscribe. | |
/// Otherwise, we will not be able unsubscribe. | |
/// </summary> | |
protected List<Subject> Subjects { get; set; } | |
#endregion Property(s) | |
#region Constructor(s) | |
public Observer() | |
{ | |
Subjects = new List<Subject>(); | |
} | |
#endregion Constructor(s) | |
#region Member(s) | |
public void Subscibe(Subject subject) | |
{ | |
// Subscribe to the event | |
subject.OnPropertyChanged += OnSubjectPropertyChanged; | |
// Keep track of the subscription. | |
Subjects.Add(subject); | |
} | |
protected void OnSubjectPropertyChanged(Object sender, EventArgs args) | |
{ | |
//Do Work | |
} | |
#region Disposable Member(s) | |
private bool Disposed { get; set; } | |
public void Dispose() | |
{ | |
Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
protected virtual void Dispose(bool disposing) | |
{ | |
if (!Disposed) | |
{ | |
if (disposing) | |
{ | |
// Make sure to unsubscribe | |
foreach (Subject subject in Subjects) | |
{ | |
subject.OnPropertyChanged -= OnSubjectPropertyChanged; | |
} | |
} | |
Disposed = true; | |
} | |
} | |
#endregion Disposable Member(s) | |
#endregion Member(s) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
public class Subject | |
{ | |
#region Event(s) | |
public event EventHandler<EventArgs> OnPropertyChanged; | |
#endregion Event(s) | |
#region Property(s) | |
private String _Property = String.Empty; | |
public String Property | |
{ | |
get | |
{ | |
return _Property; | |
} | |
set | |
{ | |
if (value != _Property) | |
{ | |
RaiseOnPropertyChangedEvent(); | |
} | |
_Property = value; | |
} | |
} | |
#endregion Property(s) | |
#region Member(s) | |
private void RaiseOnPropertyChangedEvent() | |
{ | |
// Before we raise event, make local copy of the event / delegate. | |
var target = OnPropertyChanged; | |
// The above copy operation is tread-safe, | |
// thus the following check will be. | |
if (target != null) | |
{ | |
target(this, new EventArgs()); | |
} | |
} | |
#endregion Member(s) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment