Proxy Objects

Dec 2, 2009 at 2:49 AM

Greetings.

First, I wanted to thank you for releasing Obtics.  We built our own linq-based notification framework before we discovered Bindable Linq, Continous Linq, and Obtics (among a few other minor ones).  We also recognized the need for full expression support and as such we selected Obtics for this.  Obtics has been treating us fairly well so far.  We did bang our heads against the wall for a while while trying to create some custom mappings.  I'll make another post with that story so it might help others.

This post is regarding the use of proxy objects with Obtics.  We use NHibernate as an ORM and build reactive properties and lists on top of the data retrieved from the database.  NHibernate supports lazy loading which uses proxy objects.  In other words, the object that you're adding the property changed handler to will be a proxy that points to the real implementation object.  This means that from Obtic's perspecective, it just added a PropertyChanged event handler to a ProxyPerson instance.  The PropertyChanged handler addition is passed along to the real Person object.  When the event is thrown, the sender will be the real Person object.  Obtics checks the sender (Person) against the previous reference it had (ProxyPerson) and finds that they don't match.  Because of this it doesn't recognize the update.

Here is the pertinent code from PropertyTransformation:

        void Buffer_PropertyChanged(object sender, EventArgs args)
        {
            LockForChange();

            INCEventArgs message = null;

            try
            {
                //if (object.ReferenceEquals(sender, Buffer))
                message = SIValueProvider.ValueINCEventArgs;
            }
            finally { Release(message); }
        }

Note that when we commented the line out, it seemed to correct the issue for us, but we're not sure what the ramifications would be.  Is this reference comparison needed?  If not, it would be great to eliminate it.  If it is needed, perhaps there could be a way to hook a different reference equality check method into Obtics.  Would very much appreciate feedback or questions on this.

Thanks!

Dec 2, 2009 at 5:35 AM

On the topic of considering possibilities, I was curious how hard it would be for NHibernate to use the same object for the proxy.  Based on this post and the fact that it hasn't been done yet, it doesn't seem very feasible.

http://ayende.com/Blog/archive/2009/08/28/a-guide-into-orm-implementation-challenges-lazy-loading.aspx

One thing that I should note is that all our objects override Equals to work properly with the proxy objects.  If checks like the one mentioned are indeed needed, would it be reasonable to use Equals instead?

Coordinator
Dec 2, 2009 at 11:20 AM

Hi,

It is good to hear that you are using and finding value in Obtics. I would very much like to incourage you to post about your successes, failures and dents in the forehead you experienced while using Obtics.

I could complain that the proxy is not proxying properly since it does not translate the 'sender' parameter of the event to itself. It therefore is not fully transparant and a little bit opague.This translation would incure some administrative overhead on part of the proxy class.

The 'if' statement you removed though only 'protects' against some hypothetical events that might be 'on the way' when the PropertyTransformation object would switch source. (Buffer property gets a different value) Seeing that the only information the event caries is that 'something may have changed' there would be no risk in letting the odd extra event pass through. Using Equals in this case would cary too much overhead for the supposed improvement. I think it would actually be an improvement if the 'if' statement was removed and I'll mark it as a 'To be done soon'.

Thanks for the tip,

Thomas.

Dec 3, 2009 at 7:18 PM

Your suggestion of improving the proxy was right on the money.  WPF also suffers from the exact same issue where it requires the object references to be equal.  I found a page that details how to enhance the PropertyChanged behaviour of the proxy objects to correct this.

http://www.progware.org/Blog/post/NHibernate-PropertyChanged-event-and-WPF.aspx

Implementing this fix will allow Obtics and WPF to work out of the box with NHibernate lazy loaded objects.