CSLA 4 BusinessRules System

CSLA 4 BusinessRules System

Old forum URL: forums.lhotka.net/forums/t/9886.aspx


Jaans posted on Sunday, December 19, 2010

We're working out way through converting to CSLA 4 and so far the biggest (mostly mechanical bit) is getting our business rules converted as per CSLA 4.

In one of Rocky's blog posts regarding the BusinessRules (http://www.lhotka.net/weblog/CSLA4BusinessRulesSubsystem.aspx) it's made clear that the rule class should be immutable or put differently we should not change state of the rule class because (if I understand it correctly) the same class instance is used for all properties.

Is it OK to have a rule class with state - never change it - but have another class instance with different state for another property. Eg.:

Here's the class definition:

        private class CropAtMaxLengthMutator : BusinessRule
        {
            private readonly int _maxLength = 3;

            public CropAtMaxLengthMutatorIPropertyInfo primaryProperty, int maxLength ) : base( primaryProperty )
            {
                // Validate type of property
                if ( primaryProperty.Type != typeofstring ) )
                    throw new ArgumentExceptionstring.Format"Crop at Maximum Length mutator can only apply to properties of type string. Argument: {0} Type: {1}", primaryProperty.Name, primaryProperty.Type.FullName ), "primaryProperty" );

                // Initialise state
                _maxLength = maxLength;
                InputProperties = new List<IPropertyInfo> { primaryProperty };
            }

            protected override void ExecuteRuleContext context )
            {
                var propertyValue = (string)context.InputPropertyValues[PrimaryProperty];
                context.AddOutValuePrimaryProperty, propertyValue.MaxLength_maxLength ) );
            }
        }

I'm assuming the same rule instance is used for only that property, but not for another and so it's OK (much like the new Csla.Rules.CommonRules.MaxLength(NameProperty, 20)) from CSLA?

JonnyBee replied on Sunday, December 19, 2010

Hi,

Yes it's safe to create rules like this with member variables/properties that in previous version (pre 4.x) would be in an EventArgs object.

 

RockfordLhotka replied on Sunday, December 19, 2010

The only caution is that you MUST view instance fields as immutable once the object is created. Remember that the rule object instance is used across all business objects of a given type. So if you change an instance field while the app is running, you'll affect all business objects of that type from that moment. The bugs caused by such a thing would be hard to find and solve.

It is too bad VB and C# don't have any concept about write-once fields, because that's really what's needed here.

Jaans replied on Sunday, December 19, 2010

Thanks guys - makes sense!

Say wouldn't the "readonly" field modifier (as per example above) be a useful way to try and protect the state?
It allows you to set it only during initialisation/construction

JonnyBee replied on Monday, December 20, 2010

Yes, the readonly modifier means that you can only assign a value in the constructor (or a default value at declaration)  and would protect that value from being changed and a good way to code.

But we also want to support both syntaxes

      BusinessRules.AddRule(new InfoMessage(Num1Property, "my info message"));

      BusinessRules.AddRule(new InfoMessage(Num1Property) {MessageText = "My info message"});

In the latter version there is unfortunately no possibilty for a write once property in C# or VB.NET.

But - you are safe when using readonly and only set values in the constructor.

Copyright (c) Marimer LLC