DefaultDescription, DefaultSeverity, DefaultStopProcessing not used

DefaultDescription, DefaultSeverity, DefaultStopProcessing not used

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


nelis posted on Wednesday, June 16, 2010

The BusinessRule properties mentioned in the subject are not really used. Except for DefaultDescription in InfoMessage but that rule could also use a dedicated property for that.

Then CommonBusinessRule (derived from BusinessRule) defines a new property Severity.

A bit confusing to me and probably also to end-users. They can specify these properties but won't see any behaviour change. Am I missing something?

RockfordLhotka replied on Friday, June 18, 2010

That's good feedback. So here's the thought process.

You don't have to use the base class, only the interface matters, and it doesn't require those properties.

I thought it would be wise to give some guidance on a common pattern for things people often want to set on their rules, so I put those properties on the base class.

In the end though, it is really up to the rule author to actually use them. There's nothing the base class can actually do to help this - the rule author either uses them or not.

So your argument is (I assume) that they shouldn't be there at all, and people can (and will) live without that sort of guidance.

I think that's a pretty valid argument.

nelis replied on Tuesday, June 22, 2010

(I had no idea what verify would do, but I think it's valid here)

I do agree that those properties should be removed. Especially users of the rule that did not design it themselves will be confused.

PS: I wanted to add some code to show how I used those properties in my own derived base class but copy-paste doesn't give a very readable result. Any tips?

RockfordLhotka replied on Tuesday, June 22, 2010

I copy-paste into Notepad, then copy-paste into the forum. That removes formatting and makes it readable.

nelis replied on Wednesday, June 23, 2010

Ok, I have only little experience with this code and it might need some finetuning. It is in my derived rule base class:

        /// <summary>
        /// Delegate for constructing the rule description at runtime
        /// </summary>
        public Func<RuleContext, string> DynamicDescription { get; set; }

        protected string EvaluateDescription(RuleContext context, Func<RuleContext, string> dyn)
        {
            // user specified description delegate ?
            if (DynamicDescription != null)
            {
                return DynamicDescription(context);
            }
            // user specified constant description
            else if (!string.IsNullOrEmpty(DefaultDescription))
            {
                return DefaultDescription;
            }
            // internal rule default
            else if (dyn != null)
            {
                return dyn(context);
            }
            return string.Format(Properties.Resources.CommonRules_NoRuleDescription, RuleName);
        }

        protected string EvaluateDescription(RuleContext context)
        {
            return EvaluateDescription(context, null);
        }

        protected void AddResultMessage(RuleContext context, Func<RuleContext, string> dyn)
        {
            context.Results.Add(
                new RuleResult(RuleName, PrimaryProperty, EvaluateDescription(context, dyn))
                {
                    Severity = DefaultSeverity,
                    StopProcessing = DefaultStopProcessing
                });
        }

        protected void AddResultMessage(RuleContext context, string description)
        {
            AddResultMessage(context, ctx => description);
        }

        protected void AddResultMessage(RuleContext context)
        {
            AddResultMessage(context, (Func<RuleContext, string>)null);
        }

From your derived rule you only have to call one of the AddResultMessage overloads. It resolves the description by trying

- a rule end-user specified delegate DynamicDescription

- a rule end-user specified DefaultDescription

- the internal rule description (dyn). This last one is passed as a delegate to avoid evaluation when not used (not sure if it really matters)

I'd like to know what you think about this approach

Copyright (c) Marimer LLC