Sunday, October 28, 2007

Presenter communication with the view - events or direct communication.

I just started reading Jeremy Miller's excellent blog post series on Build your own CAB series. I'm currently up to his 6th post on "View to Presenter Communication" and found the discussion of using events vs. callbacks on the presenter very interesting and relevant to my current work.

Let me share a recent experience...

I've been using events from my view to communicate with the presenter and ran across a bug that was related to using event inadvertently. While working one day, I accidentally pressed Ctrl-L and duplicated a line in my presenter constructor. The line I duplicated was a hook of a view event. This caused my presenter event delegate to be called twice.

I found out later that my unit tests for the presenter were correctly checking that I wired all the view events but they were not checking that the events were only wired once. All my integration testing was in debug mode! Then ran the application in release mode. BOOM!

It turns out the events fired in a different order under release mode and caused a null reference exception with a state change in the model.

If the purpose of events is to allow multiple listeners, when would I ever design the use of a single event to communicate multiple methods in the presenter?

Perhaps I would but that appears to be more of an edge case and not very good design. It would lead me back towards a design where events don't communicate specifics but something more abstract as the 'SomethingChanged' event.

Would I ever have multiple presenters for the same view? Never.

So is using events a good design principle to create loose coupling? Yes, but only if you require multiple listeners. If you don't, are you over engineering the solution? Perhaps.

Now when it comes to the model, events are essential! I have multiple presenters listening to model objects!

I've also been fighting memory leaks due to the use events on my model objects. My model has certain objects that can be retrieved from cache and exist for the life of the process. When my presenter hooks these events, it was causing my presenter to not unload when the view was destroyed. This cause me to have to disconnect my model events from the model objects when the presenter was disposed. This also required me to dispose my presenter when the code that first created the presenter fell out of scope.

On a side note, I found the memory leak using SciTech's excellent memory profiler. If you are creating WinForm applications, I suggest you download it and try it against your application. You might be surprised to find you have memory leaks in your applications. It also has an API so you can build integration or unit tests to check for memory leaks.