how to: simplified/individual change notification

Discussion of open issues, suggestions and bugs regarding Entity Developer - ORM modeling and code generation tool
Post Reply
mindplay
Posts: 148
Joined: Tue 13 Dec 2011 22:58
Location: Ithaca, NY

how to: simplified/individual change notification

Post by mindplay » Thu 22 Dec 2011 17:50

The "Property Change Notifiers" generate far too much code and too many function calls for my taste - all I need is a notification that a property has been changed, and only for a few, select properties.

Add the following extended property to your template:
Near the beginning of the GenerateProperty() method, add the following:

Code: Select all

bool propCallback = (bool) property.GetProperty("PropertyChangeCallback");
Within that method, find the following line:

Code: Select all

this._ = value;
Immediately after that line, paste in the following:

Code: Select all


                this.OnChanged();

That enables you to turn on the callback generation for a specific property.

Next, find the GenerateExtensibilityMethodDefinitions method and select the following section of code:

Code: Select all

    if (supportPropertyChanging) {
      string defaultNamespace = codeProvider.GetValidIdentifier(model.GetDefaultNamespace());
      foreach (HibernateProperty property in type.Properties ) {
#> 
        partial void OnChanging( value);
        partial void OnChanged();

 
        partial void OnChanging( value);
        partial void OnChanged();
 
        partial void OnChanging( value);

        partial void OnChanged();

 
        partial void OnChanging( value);
        partial void OnChanged();
<#+
        }
      }
    }
For a property with change-notification turned on, the generated code looks something like this:

Code: Select all

        private string _Name;

        #region Extensibility Method Definitions
        
        partial void OnCreated();
        partial void OnNameChanged();
        
        #endregion

        protected internal virtual string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
                this.OnNameChanged();
            }
        }
Note that this works best with the "field" or "nosetter" access strategy, as both of these avoid invoking the set-method when NH hydrates an object with values from the database - using "property" access strategy will cause the callback to be invoked when you load an object, which is probably not what you want.

Also note that this is currently only implemented for scalar properties - not for navigation properties. You need it for navigation properties, you could probably follow this example and make the change yourself.

Hope this is useful to somebody else :-)

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Thu 29 Dec 2011 09:40

Thank you for sharing your experience.
There is a similar template option (PropertyChangeNotifiers) which is applied to all model properties.

mindplay
Posts: 148
Joined: Tue 13 Dec 2011 22:58
Location: Ithaca, NY

Post by mindplay » Thu 29 Dec 2011 14:10

Shalex wrote:There is a similar template option (PropertyChangeNotifiers) which is applied to all model properties.
As explained in line 1 of my post.

Hmm...

mindplay
Posts: 148
Joined: Tue 13 Dec 2011 22:58
Location: Ithaca, NY

Post by mindplay » Fri 30 Dec 2011 18:38

For the record, I decided to revert this change.

I learned that partial methods are in fact merely a specification - if they are not implemented by another partial class, they do not in fact result in any generated code - and calls to unimplemented partial methods also do not compile into function-calls.

So instead, I made a much more subtle change.

The part I don't need or like is all of the events that are being generated - these are not partial methods, which means you do have an overhead of two extra function-calls from setting any property.

This is easily removed by simply commenting out the INotifyPropertyChanging and INotifyPropertyChanged interface declarations and their implementations, as well as commenting out the calls to SendPropertyChanging() and SendPropertyChanged().

Since there is no overhead from doing so, I like having all the Changing() and Changed() methods defined and available in the generated partial classes.

It would be nice if the callbacks and events were two different features though, as generating events (to most people) is most likely dead weight 95% of the time.

Helen
Devart Team
Posts: 127
Joined: Wed 07 Sep 2011 11:54

Post by Helen » Tue 03 Jan 2012 15:57

We will implement the possibility to manage these two features using different template properties.

Helen
Devart Team
Posts: 127
Joined: Wed 07 Sep 2011 11:54

Post by Helen » Thu 12 Jan 2012 15:01

The possibility to generate extensibility partial On<property name>Changing and partial On<property name>Changed methods separately with the 'PropertyChangePartialMethods' template property is added.

This feature is available in the latest 4.2.110 build of Entity Developer.
The new build can be downloaded from http://www.devart.com/entitydeveloper/download.html (the trial and free versions) or from Registered Users' Area (provided that you have an active subscription).

For the detailed information about the improvements and fixes available in Entity Developer 4.2.110, please refer to
http://www.devart.com/forums/viewtopic.php?t=23135

mindplay
Posts: 148
Joined: Tue 13 Dec 2011 22:58
Location: Ithaca, NY

Post by mindplay » Mon 16 Jan 2012 19:52

This works nicely, thank you!

Post Reply