CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Forum has moved

New location: CSLA .NET forum


CSLA .NET Resources:
  • CSLA .NET forum
  • CSLA .NET home page
  • Firing business rules on property changed for a private backing field

    rated by 0 users
    Answered (Verified) This post has 1 verified answer | 1 Reply | 1 Follower

    Not Ranked
    1 Posts
    EGraeb posted on Tue, Oct 14 2014 4:02 PM

    We are just upgrading from an older version of CSLA to the new framework (4.5.6) and having a little difficulty with one scenario.

    I have a CSLA class (Model) referencing properties on another CSLA class (Relation) as a private backing field. The registration is setup like this:

    Public Shared ReadOnly ReferenceProperty As PropertyInfo(Of ReferenceType) = RegisterProperty(Of ReferenceType)(Function(c) c.ReferenceType, "Reference Type", RelationshipTypes.PrivateField)
            Public Property ReferenceType() As ReferenceType
                Get
                    Return GetProperty(ReferenceProperty,_reference.ReferenceType)
                End Get
                Set(ByVal value As ReferenceType)
                    SetProperty(ReferenceProperty,_reference.ReferenceType,value)
                End Set
            End Property

    The "Model" montors for changes to the property in "Relation" and fires OnPropertyChanged("string name of property") on itself to fire the business rules on itself in case it's changed elsewhere. The property in Relation and the property in Model have the same string name:

    Private Sub ReferencePropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Handles _reference.PropertyChanged
                If Me.GetType.GetMembers.Select(Function(m) m.Name).Contains(e.PropertyName) Then
                    OnPropertyChanged(e.PropertyName)
                End If
            End Sub

    The problem is that firing this OnPropertyChanged doesn't fire the business rules tied to the Model property any more. I can fire the business rule manually by adding a little more reflection and that works fine:

    Dim prop As IPropertyInfo = FindProperty(e.PropertyName)
    If prop IsNot Nothing Then
             BusinessRules.CheckRules(prop)
    End If

    Whenever I need to use reflection though I run under the assumption I must be doing something wrong. Is there something extra I need to do to have validation rules fire OnPropertyChanged for private backing fields?

     

    Answered (Verified) Verified Answer

    Top 10 Contributor
    2,279 Posts
    Verified by EGraeb

    Hi,

    OnPropertyChanged on a BO must NEVER be used to trigger business rules!!!
    It must ONLY be used to notify the UI of changes to content or state of a property.

    There are 3 ways to trigger a business rules for a property:

    • BusinessRules.CheckRules(propertyInfo)
    • PropertyHasChanged(propertyInfo)
    • CheckPropertyRules(propertyInfo)

    The difference between PropertyHasChanged and CheckPropertyRules is that PropertyHasChanged will also mark the object as Dirty before calling CheckPropertyRules that in turn will call BusinessRules.CheckRules and call OnPropertyChanged as necessary.

    So you could write the event handler as:

    private void ReferencePropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // you could even check that the propertyInfo is flagged as PrivateField - not shown 
        var myProperty = FieldManager.GetRegisteredProperties().FirstOrDefault(p => p.Name == e.PropertyName);     if (myProperty != null)     {         PropertyHasChanged(myProperty);         // or if you do not want to mark the object as dirty          // CheckPropertyRules(myProperty);     } }

    and just for reference this is the PropertyHasChanged and CheckPropertyRules method:

    protected virtual void PropertyHasChanged(Csla.Core.IPropertyInfo property)
    {
      MarkDirty(true);
      CheckPropertyRules(property);
    }
    protected virtual void CheckPropertyRules(IPropertyInfo property)
    {
      var propertyNames = BusinessRules.CheckRules(property);
      if (ApplicationContext.PropertyChangedMode == ApplicationContext.PropertyChangedModes.Windows)
        OnPropertyChanged(property);
      else
        foreach (var name in propertyNames)
          OnPropertyChanged(name);
    }

    Jonny Bekkum, Norway CslaContrib Coordinator

    Page 1 of 1 (2 items) | RSS

    Copyright (c) 2006-2014 Marimer LLC. All rights reserved.
    Email admin@lhotka.net for support.
    Powered by Community Server (Non-Commercial Edition), by Telligent Systems