Customizing Business Rules at runtime

This series looks at the Business Logic Layer of an application from how my Peter’s Business Logic Driven UI (“BLD”) implements it. Use the “Understanding the BLL” Category to see all articles.

In the last article, you were introduced to Descriptor objects. Now you will see what I think is their most important feature: the ability to customize the business rules at runtime.

DataFieldDescriptor objects may describe a business rule and structure of a DataField, but are globally defined and must not be modified at runtime. BLD introduces the PeterBlum.DES.DataAnnotations.ActiveDataField class as a wrapper around the global DataFieldDescriptor. It exposes properties and methods that let you edit the business rules. For example, you can assign its DisplayName property to override the one in DataFieldDescriptor. If you don’t override it, DisplayName returns the localized name from the DataFieldDescriptor.

The Business Logic Layer (“BLL”) uses the PeterBlum.DES.DataAnnotations.ICustomizeDataField interface to let your BLL Entity class edit the ActiveDataField object. ICustomizeDataField adds a single method, CustomizeDataField(), which is passed the ActiveDataField object.

In the previous article, you saw how a DataFieldDescriptor for the CategoryName DataField was used to establish a disabled textbox and the text of a label. Let’s see how BLD lets you modify the IsReadOnly and DisplayName business rules of the ActiveDataField object.

[C#]

using DESDA=PeterBlum.DES.DataAnnotations;
public partial class Category : DESDA.ICustomizeDataField
{
   public void CustomizeDataField(DESDA.ActiveDataField activeDataField)
   {
      switch (activeDataField.DataField)
      {
         case "CategoryName":
            activeDataField.IsReadOnly = !CanUserEdit(); // left for you to write
            activeDataField.DisplayName = GetDisplayName(); // left for you to write
            break;
 
      }
   }
}

[VB]

Imports DESDA=PeterBlum.DES.DataAnnotations
Public Partial Class Category
  Implements DESDA.ICustomizeDataField
  Public Sub CustomizeDataField(activeDataField As DESDA.ActiveDataField) _
      Implements DESDA.ICustomizeDataField.CustomizeDataField
    Select Case activeDataField.DataField
      Case "CategoryName"
            activeDataField.IsReadOnly = Not CanUserEdit() ' left for you to write
            activeDataField.DisplayName = GetDisplayName()  ' left for you to write
        Exit Select
    End Select
  End Sub
End Class

Your code does not edit the actual DataFieldDescriptor, but it can access it through the ActiveDataField.GlobalDataFieldDescriptor property to help build the actual business rule.

Now let’s utilize this in your UI layer. BLD boxes anything specific to a single DataField in a Field Template object. The PeterBlum.DES.BLD.BaseFieldTemplate class from which all Field Templates are created makes a fully prepared ActiveDataField available as a property. Supposing the data editing control for this Field Template is a TextBox, you might write this code:

[C#]

((TextBox)DataControl).Enabled = !ActiveDataField.IsReadOnly;

[VB]

CType(DataControl, TextBox).Enabled = Not ActiveDataField.IsReadOnly

The ActiveDataField.DisplayName property is used by the Field Template for its validator error messages, when they contain the token “{LABEL}”. If you want the customized DisplayName to appear in a Label control, use the BLDLabel control (a subclass of the Label control) and set its AssociatedControlID property to the ID of the BLDDataField control (the host control that loads the Field Template). BLDLabel will get the ActiveDataField object through the BLDDataField.

Here’s roughly what the code of the BLDLabel control looks like as it assigns its Text property.

[C#]

Control vAssociatedControl = FindControl(AssociatedControlID);
if ((vAssociatedControl != null) && (vAssociatedControl is BLDDataField))
   this.Text = ((BLDDataField)vAssociatedControl).FieldTemplate.ActiveDataField.DisplayName;

[VB]

Dim vAssociatedControl As Control = FindControl(AssociatedControlID)
If (Not vAssociatedControl Is Nothing) And (vAssociatedControl is BLDDataField)) Then
   Me.Text = CType(vAssociatedControl, BLDDataField).FieldTemplate.ActiveDataField.DisplayName
End If

For more on this subject, see the topics in the BLD User’s Guide.

1 Comment

  • Why is the code for setting the Label.Text so verbose? When will is this code called? If you are using your BLD controls, why they can't set their properties by themselves? What will make me to use your BLD framework for UI?
    Do know that abbreviation for Business Driven Logic UI is BDL?

Comments have been disabled for this content.