Clearing and reloading instance rules

Clearing and reloading instance rules

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


Fintanv posted on Wednesday, August 27, 2008

I have a requirement where I need to reload some instance rules based on the value of a product name property.  The rules are defined in the database, are configured by the user, and can be tied to a particular product.  These rules are very simple (MIN, MAX, REGEX, IN <i.e. must be a member of a defined list of values>.  I dynamically load up the rules when the BO is first populated.  However if the value of the product name changes (which it may do at several trigger points in the system), then I need to dump the existing rules and re-load them.

I have a solution, but it involves modifying the Csla source.  Not something I want to do unless it is absolutely necessary, and so I am running my solution by the experts to see if there is a better way.

Any feedback is welcome, and thanks in advance!

My modifications are to the classes:

ValidationRules

    public void ClearInstanceRules()
    {
        GetInstanceRules(true).ClearRules();
        _brokenRules = null;
        CheckRules();
    }

and...

ValidationRulesManager       

internal void ClearRules()
    {
        RulesDictionary.Clear();
    }

Fintanv replied on Wednesday, August 27, 2008

Found my own solution to modification of the framework.  The following code does the trick via reflection and is implemented as an extension method.

public static void ClearInstanceRules(this Csla.Validation.ValidationRules item)

{

// get the rule manager

MethodInfo mi = item.GetType().GetMethod("GetInstanceRules", BindingFlags.Instance | BindingFlags.NonPublic);

var ruleManager = mi.Invoke(item, new object[] { true });

// clear the instance rules

PropertyInfo pi = ruleManager.GetType().GetProperty("RulesDictionary", BindingFlags.Instance | BindingFlags.NonPublic);

var dictionary = pi.GetValue(ruleManager, null);

MethodInfo dmi = dictionary.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public);

dmi.Invoke(dictionary, null);

// get the broken rules variable and re-set it to null

FieldInfo fi = item.GetType().GetField("_brokenRules", BindingFlags.NonPublic | BindingFlags.Instance);

fi.SetValue(item, null);

// recheck the remaining (per-type) rules

item.CheckRules();

}

rsbaker0 replied on Wednesday, August 27, 2008

You might take a look at this thread where we discussed clearing the per-type rules also:

http://forums.lhotka.net/forums/thread/25340.aspx

Clearing individual instance rules might be easier, but there might be issues that aren't obvious on the surface. For example, if one of the rules you are removing is currently broken, it might not be possible to fix it (except that I see you are trying to handle that particular case in your code above) 

Fintanv replied on Thursday, August 28, 2008

Thanks for the info.  I did take a look through the thread on per-type rules but did not see anything that directly impacted my situation.  I have tested my solution and it works as I hoped.  Indeed if there is a broken rule, it is cleared.  Something I want to happen.  When I load the new rules (code not shown) then they are checked and may potentially generate new broken rules.  Since most of these rules related to tolerances on measured values, I get the behavior I want.

Copyright (c) Marimer LLC