New Posts New Posts RSS Feed: Entity.OnPropertyChanged not called
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Entity.OnPropertyChanged not called

 Post Reply Post Reply
Author
stephenmcd1 View Drop Down
DevForce MVP
DevForce MVP


Joined: 27-Oct-2009
Location: Los Angeles, CA
Posts: 166
Post Options Post Options   Quote stephenmcd1 Quote  Post ReplyReply Direct Link To This Post Topic: Entity.OnPropertyChanged not called
    Posted: 28-Feb-2012 at 6:26pm
In our entities, we often override Entity.OnPropertyChanged to execute logic when a property changes.  After a lot of debugging, I just found out that OnPropertyChanged does not get called if there are not any subscribers to the Entity.PropertyChanged event.  I can understand the rational behind this - some kind of optimization I suppose.  But in our case, we always want OnPropertyChanged to be fired - even if nobody external is watching the entity for changes, the entity itself might be waiting for property changes.

As a hack, I've updated our entities to attach a dummy handler to PropertyChanged when they are first created and that seems to fix the problem.....but it doesn't feel like a very nice hack.  Is there a reason that EntityAspect.FirePropertyChanged short-circuits if there are no subscribers?  It doesn't seem like it'd be that much of an overhead and it seems like non-obvious behavior to me.
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 29-Feb-2012 at 12:22pm
Hi stephenmcd1,

What version are you using?

I believe this issue has been fixed as of 6.1.5. Can you confirm that we're talking about the same behavior here? Below is my test code.

 public partial class Employee {

    protected override void OnPropertyChanged(PropertyChangedEventArgs e) {
      if (e.PropertyName == "Country" && this.Country == "Country") {
        this.Country = "Narnia";
      }
    }
}

var emp = mgr.CreateEntity<Employee>();
emp.Country = "Country";
Assert.IsTrue(emp.Country == "Narnia");


Back to Top
stephenmcd1 View Drop Down
DevForce MVP
DevForce MVP


Joined: 27-Oct-2009
Location: Los Angeles, CA
Posts: 166
Post Options Post Options   Quote stephenmcd1 Quote  Post ReplyReply Direct Link To This Post Posted: 29-Feb-2012 at 4:51pm
We are still on 6.1.3.1 so that's probably why we aren't seeing this behavior.  The test you provide is exactly the behavior I was expecting (but not seeing).  Thanks for looking into it!
Back to Top
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Posted: 06-Jun-2012 at 8:19pm
Hi, 

We're still using Devforce 6.1.4 and we experienced the same problem, can you provide us a Hotfix Patch? 

Thanks,
Von
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 07-Jun-2012 at 1:01pm
Hi Von,

We don't normally provide a hot fix patch to an older version. You can either upgrade to our latest 6.1.7.1 which can be found in our website, or to 6.1.5. I will PM you the link to download this.
Back to Top
stephenmcd1 View Drop Down
DevForce MVP
DevForce MVP


Joined: 27-Oct-2009
Location: Los Angeles, CA
Posts: 166
Post Options Post Options   Quote stephenmcd1 Quote  Post ReplyReply Direct Link To This Post Posted: 07-Jun-2012 at 2:21pm
If you can't upgrade to the latest version, you can use a hack similar to the one we needed to have until we were able to upgrade.  I made a helper method that will attach a dummy event handler which will cause the OnPropertyChanged method to be called like normal.  Here is some sample code:
        #region Property Changed Helper

        /// <summary>
        /// Whether we've attached the handler to this instance.
        /// </summary>
        private bool _propertyChangeEventHandlerAdded;

        /// <summary>
        /// An instance of <see cref="PropertyChangedEventHandler"/> that we can use for
        /// all instances as a dummy handler.
        /// </summary>
        private static readonly PropertyChangedEventHandler _cachedHandler = delegate { };

        /// <summary>
        /// Ensures that <see cref="Entity.OnPropertyChanged"/> will be fired when properties change.
        /// </summary>
        /// <remarks>
        /// To ensure the method gets called, we need to attach a dummy event handler to 
        /// <see cref="Entity.PropertyChanged"/> - otherwise, DevForce won't even call the
        /// method.
        /// </remarks>
        private void EnsureOnPropertyChangedFires()
        {
            if (_propertyChangeEventHandlerAdded)
                return;

            PropertyChanged += _cachedHandler;
            _propertyChangeEventHandlerAdded = true;
        }

        #endregion

I put that code into the base class that all our entities derive from.  Then when I wanted OnPropertyChanged to get fired, I called EnsureOnPropertyChangedFires() (and it's safe to call that method multiple times).  We had the method call in a couple of different places because there are times when we actually didn't want OnPropertyChanged to be called.  But to keep things simple, you could probably put that call in the entity's constructor maybe.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down