Thursday, March 13, 2008 #

Modifica delle proprietà e INotifyPropertyChanged

Spesso in rete trovo degli esempi di implementazione dell'interfaccia INotifyPropertyChanged che non mi piacciono per niente (anche su MSDN). In particolare sono interessato a come e quando generare l'evento di notifica della modifica di una proprietà. Sembra che quasi tutti ignorino il fatto di generare la notifica solo quando il valore della proprietà è stato effettivamente modificato.

Credo invece sia importante gestire correttamente tale notifica, per una serie di ragioni, prima su tutte le performance. Nelle mie implementazioni di entità gestisco l'impostazione del nuovo valore e la notifica in modo centralizzato, con un metodo protected implementato nella classe base da cui derivano tutte le entità, con il compito di verificare effettivamente se il valore è  cambiato oppure no prima di impostare il nuovo valore e generare l'evento. E' chiaro che tutte le entità concrete devono rispettare il pattern di richiamare tale metodo nei rispettivi setter ed implementare l'override del metodo Equal (e quindi obbligatoriamente anche GetHashCode) in modo da comparare anche proprietà che rappresentano altre entità.

Sto sbagliando, nel senso, mi sto facendo troppi problemi?

posted @ Friday, March 14, 2008 8:54 AM | Feedback (27)

Implementare ISupportInitialize nelle classi entità

Sto realizzando l'ennesima versione di una classe base astratta da utilizzare per tutte le entità aziendali. Questa classe dovrà implementare alcune interfacce basilari, tra le quali INotifyPropertyChanged, e pensavo anche alla ISupportInitialize. Il dubbio che ho nell'implementare quest'ultima interfaccia è se devo generare o no gli eventi di notifica del cambio dei valori delle proprietà nel momento che a seguito della chiamata al metodo ISupportInitialize.EndInit() vado ad impostare tutti i valori delle proprietà modificate dopo la chiamata a ISupportInitialize.BeginInit().

Per chiarezza (?), segue il frammento dell'implementazione della classe ed in particolare la parte di implementazione dell'interfaccia ISupportInitialize.

      #region ISupportInitialize implementation
      public void BeginInit()
      {
         if (!m_Initializing)
         {
            m_InitializeData = new Hashtable();
            m_Initializing = true;
         }
      }
 
      public void EndInit()
      {
         if (m_Initializing)
         {
            m_Initializing = false;
            Type t = this.GetType();
            foreach (DictionaryEntry entry in m_InitializeData)
            {
               PropertyInfo pi = t.GetProperty((string)entry.Key);
               if (pi != null)
               {
                  pi.SetValue(this, entry.Value, null);
               }
            }
            m_InitializeData = null;
         }
      }
      #endregion
 

In questa implementazione nel metodo EndInit si impostano i valori di tutte le proprietà modificate dopo la chiamata alla BeginInit bufferizzate in una tabella hash, chiamando il metodo SetValue via reflection che invoca il setter della relativa proprietà, la quale noticherà la modifica generando l'evento relativo all'implementazione della INotifyPropertyChanged (non mostrata nel frammento di codice).

Quindi ecco il dubbio: è corretto così, oppure devo disabilitare le notifiche del cambio delle proprietà quando sono nella EndInit? Personalmente credo che come è scritta ora non vada bene. Da quello che ho capito io, lo scopo dell'implementazione dell'interfaccia ISupportInitialize è di impostare tutte le proprietà senza craere problemi di incoerenza sullo stato dell'entità stessa e quindi, credo che non debbano essere generare le relative notifiche, le quali potrebbero dare problemi ai client "in ascolto".

Sono graditi commenti e/o suggerimenti.

posted @ Thursday, March 13, 2008 11:13 AM | Feedback (237)