Observing .NET with IObservable

Erik Meijer and Brian Beckman introduced the concept of IObservable for .NET in their Channel 9 video “Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx)”, which is getting included in .NET version 4. .NET events present a number of challenges to developers. Weak event managers, like the Composite Framework’s (Prism) “EventAggregator”, act as an event publish-subscribe proxy to decouple direct event references for better memory garbage collection. Silver Bay Labs did a good overview video on the subject, but Microsoft’s MSDN technical concepts documentation accurately describes the problem as well (see the section under “Subscribing Using Strong References”).

The Quick Problem Summary: .NET events are usually directly referenced through multi-cast delegates (a collection of classes that act like function pointers). I would call these references pointers, but these are managed references and this is important because managed references are managed through .NET garbage collection. When an object (”observer”) references an event on an object (”observable”) and the observable object goes out of scope (kind of), .NET garbage collection will not clean-up the observable, because of the observer’s event reference. Got it? You almost need a “Disposing” event on observable objects, so that observers can be notified and properly de-reference the subscribed event.

What’s the Point? … First a Major WPF/Silverlight Eventing Digression

I did a lot of WPF development earlier this year with the Model-View-ViewModel pattern. A lot of the classes in this pattern will implement the INotifyPropertyChanging and INotifyPropertyChanged. There is a lot of great debate around implementing these notification interfaces versus using the WPF DependencyProperty. Ultimately, you end up with all of the public properties in these classes looking something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public abstract class BaseModel : INotifyPropertyChanging, INotifyPropertyChanged
{
   public event PropertyChangingEventHandler PropertyChanging;
   public event PropertyChangedEventHandler PropertyChanged;
 
   protected virtual void OnPropertyChanging(string propertyName)
   {
      if (this.PropertyChanging != null)
      {
         this.PropertyChanging(
            this, 
            new PropertyChangingEventArgs(propertyName));
      }
   }
 
   protected virtual void OnPropertyChanged(string propertyName)
   {
      if (this.PropertyChanged != null)
      {
         this.PropertyChanged(
            this, 
            new PropertyChangedEventArgs(propertyName));
      }
   }
}
 
public class BusinessModel : BaseModel
{
   private string value;
 
   public string Value
   {
      get
      {
         return this.value;
      }
 
      set
      {
         this.OnPropertyChanging("Value");
         this.value = value;
         this.OnPropertyChanged("Value");
      }
   }
}

String Madness! That’s right! You’ve got strings everywhere, so uninstall your code refactoring utilities, because they are now useless. In fact, the Joy of Code released a model unit test framework for just this kind of problem (along with other not-so-useless features).

A Strongly-Typed Solution: There are more complex and robust solutions being developed on CodePlex, but they hadn’t worked out a solution at the time I wrote my own. So, we can improve this stringy solution with some effective use of .NET Lambda expressions… (Super-Secret Tip: download the source for the unit testing framework Moq and review the “Setup” and “Verify” methods.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public abstract class BaseModel : INotifyPropertyChanging, INotifyPropertyChanged
{
   public event PropertyChangingEventHandler PropertyChanging;
   public event PropertyChangedEventHandler PropertyChanged;
 
   protected virtual void OnPropertyChanging<T>(Expression<Func<T>> expression)
   {
      var memberExpression = expression.Body as MemberExpression;
 
      if (this.PropertyChanging != null)
      {
         this.PropertyChanging(
            this, 
            new PropertyChangingEventArgs(memberExpression.Member.Name));
      }
   }
 
   protected virtual void OnPropertyChanged<T>(Expression<Func<T>> expression)
   {
      var memberExpression = expression.Body as MemberExpression;
 
      if (this.PropetyChanged != null)
      {
         this.PropertyChanged(
            this, 
            new PropertyChangedEventArgs(memberExpression.Member.Name));
      }
   }
}
 
public class BusinessModel : BaseModel
{
   private string value;
 
   public string Value
   {
      get
      {
         return this.value;
      }
 
      set
      {
         this.OnPropertyChanging(() => this.Value);
         this.value = value;
         this.OnPropertyChanged(() => this.Value);
      }
   }
}

Still Interested in IObservable?

Because of my experience with the problems in .NET event references and the INotifyPropertyChang[...] interface implementations, I wrote a new solution called “IObservable”. Sweet! Now, circle back to the start of this post… Doh! Erik told the world about his IObservable and then Microsoft baked it into .NET 4 in the reactive framework. What’s more, their implementation looks nothing like what I did.

The Notification Solution Described

Download the zip file above and review the C# code file. The quickest description would be an example…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class MyObservable : MemberNotifier // all the goodies
{
   private string value;
 
   public string Value
   {
      get { return this.value; }
 
      set
      {
         this.OnChanging(() => this.Value);
         this.value = value;
         this.OnChanged(() => this.Value);
      }
   }
}
 
public class ObservableTestFixture
{
   [Fact] // xUnit test
   public void TestMemberNotifications()
   {
      var observable = new MyObservable();
      int changingCount = 0, changedCount = 0;
      string changingPropertyName = null, changedPropertyName = null;
 
      // the anonymous delegate is passed directly into the function call
      // so, there are no managed references to clean up
      // However, you should use "UnregisterObserver" if the delegate is assigned to an object instance
      observable.RegisterObserver((o, args) =>
         {
            // for the record, I don't like these "is" checks... it's most definately smelly code
            // however, the interface for "args" can be implemented using any method (enums, bools, etc.)
            if (args is MemberChangingNotification)
            {
               changingCount++;
               changingPropertyName = arg.MemberExpression.Member.Name;
            }
            else if (args is MemberChangedNotification)
            {
               changedCount++;
               changedPropertyName = arg.MemberExpression.Member.Name;
            }
         });
 
      observable.Value = "test";
 
      // strongly-typed sweetness
      var expectedPropertyName = ExpressionHelper.GetMember(() => see.Value).Name;
 
      Assert.AreEqual(1, changingCount);
      Assert.AreEqual(expectedPropertyName, changingPropertyName);
      Assert.AreEqual(1, changedCount);
      Assert.AreEqual(expectedPropertyName, changedPropertyName);
   }
}

Performance? Because I use the reflection operations from the lambda expressions, I’d be curious to know if anyone has experienced performance degradation of any sort with this solution. The .NET team has done so much to improve reflection lookups that it’s usually not a problem, even in the enterprise.

Event Driven Architecture

Yesterday, I finished reading “Event Processing in Action” by Manning Publishing (not yet published to the public at the time of this post), which effectively describes the considerations that need to be made in Event Driven Architecture. The book covers the topic with examples in four different languages, Aleri, Apama, Esper, and Etalis. Because these languages stand alone in many respects, it’s a refreshing perspective to step outside of Java or .NET and consider the many possibilities. The book was a solid read and I would recommend it to anyone interested in the subject. Of course, the book’s content has already begun to spin my head gears into thinking through the problems and solutions outlined here for even better solutions.

What do you think?

Please comment and leave your thoughts on this solution, on Microsoft’s Reactive framework, weak eventing and the Composite Framework’s EventAggregator, etc.

:) PS: I am working on my birthday today and writing stuff like this, so be kind. :)

Updates

Later today (WPF/Silverlight Notifications):
A much respected ex-coworker of mine suggested more could be done to simplify property setters and mentioned that Glenn Block was working on a solution that might be included in the Managed Extensibility Framework. I haven’t reached out to Glenn yet, but here’s a quick and untested shot for WPF and Silverlight:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// I'll take a shot at Wordpress coding... where's my intellisense?!
public abstract class PropertyNotifier : 
   MemberNotifier, 
   INotifyPropertyChanging, 
   INotifyPropertyChanged
{
   // the only requirement for INotifyPropertyChanging 
   public event PropertyChangingEventHandler PropertyChanging;
 
   // the only requirement for INotifyPropertyChanged
   public event PropertyChangedEventHandler PropertyChanged;
 
   protected override void OnChanging<T>(Expression<Func<T>> expression)
   {
      base.OnChanging(expression); // notify using the Observable pattern
 
      if (this.PropertyChanging != null)
      {
         var memberExpression = expression.Body as MemberExpression;
 
         // notify using events
         this.PropertyChanging(
            this, 
            new PropertyChanging(memberExpression.Member.Name));
      }
   }
 
   protected void OnChanged<T>(Expression<Func<T>> expression)
   {
      base.OnChanged(expression); // notify using the Observable pattern
 
      if (this.PropertyChanged != null)
      {
         var memberExpression = expression.Body as MemberExpression;
 
         // notify using events
         this.PropertyChanged(
            this, 
            new PropertyChanged(memberExpression.Member.Name));
      }
   }
 
   // wrap a setter in Changing and Changed notifications
   protected void SetWithNotifications<T>(
      Expression<Func<T>> expression, 
      Action setter)
   {
      this.OnPropertyChanging(expression);
      setter();
      this.OnPropertyChanged(expression);
   }
}
 
// now, implementing becomes incredibly simple!
public class MyObservable : PropertyNotifier
{
   private string value;
 
   public string Value
   {
      get { return this.value; }
 
      set
      {
         // pass the member expression and the setter action delegate
         this.SetWithNotifications(() => this.Value, () => this.value = value);
      }
   }
}
 
// what about multiple notifications?
public class MyObservablePerson : PropertyNotifier
{
   private string firstName;
   private string lastName;
 
   public string FirstName
   {
      get { return this.firstName; }
      set
      {
         // ... [input validation ?] ...
 
         this.SetWithNotifications(
            () => this.FirstName, // member expression
            () => // setter
            {
               // wrap setter with change notifications for FullName
               this.OnPropertyChanging(() => this.FullName);
               this.firstName = value;
               this.OnPropertyChanged(() => this.FullName);
            });
      }
 
   public string LastName
   {
      get { return this.lastName; }
      set
      {
         // ... [input validation] ...
         this.SetWithNotifications(
            () => this.LastName, 
            () => 
            {
               this.OnPropertyChanging(() => this.FullName);
               this.lastName = value;
               this.OnPropertyChanged(() => this.FullName);
            });
      }
 
      public string FullName
      {
         get      
         {
            return String.Format(
               CultureInfo.CurrentCulture, 
               "{1}, {0}", 
               this.FirstName, 
               this.LastName);
         }
      }
   }
}
 
/*
   FYI: You could also overload the SetWithNotifications method 
   to accept a primary member expression for the setter and a
   list of secondary member expressions for notification...
   The call would end up looking something like:
      this.SetWithNotifications(
         () => this.Value, 
         {
            () => this.DependantValue1,
            () => this.DependantValue2,
            () => this.DependantValue3
         },
         this.value = value);
 
   The method could simply iterate the dependencies,
   calling Changing() and Changed() for each.
*/

5 Responses to “Observing .NET with IObservable”

Leave a Reply