IgorShare Thoughts and Ideas

Consulting and Training

PowerShell Rules Engine: How-To Technical Details

Posted by Igor Moochnick on 02/15/2008

In my recent article, Marrying Workflows into PowerShell (Part 1 of 2), PowerShell Rules Engine, I’ve shown an example of how to use a Rule Set editor, shipped with Workflows Foundation, in your own application and how to evaluate rules against managed objects. Actually, PowerShell was used as a specific example of how to use this technology.

I haven’t invented anything new and this information is readily available from different public sources, but, I think, it’ll be better if I’ll explain how it works for the readers of this blog.

There are 3 simple steps to get this technology to work for you:

  1. Create and edit rule sets via the Rule Set Dialog and serialize the rules into an XML
  2. Load (deserialize) the Rule Set from an XML file
  3. Evaluate/apply the rules against your own objects

The step #1 is implemented in the ShowDialog function:

   1: public static RuleSet ShowRulesDialog(Type targetType, RuleSet ruleSetIn, string rulesFileName)
   2: {
   3:     RuleSet ruleSet = ruleSetIn ?? new RuleSet();
   4:     RuleSetDialog ruleSetDialog = new RuleSetDialog(targetType, null, ruleSet);
   5:     DialogResult dr = ruleSetDialog.ShowDialog();
   6:     if (dr == DialogResult.OK)
   7:     {
   8:         ruleSet = ruleSetDialog.RuleSet;
   9:         if (ruleSet == null)
  10:             return null;
  12:         XmlTextWriter writer = new XmlTextWriter(rulesFileName, Encoding.Unicode);
  14:         WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
  15:         serializer.Serialize(writer, ruleSet);
  17:         writer.Flush();
  18:         writer.Close();
  19:     }
  21:     return ruleSet;
  22: }


Note line #3 – if you’ll provide a valid instance of a Rule Set – the editor will allow you to edit it, if you don’t have a Rule Set, provide a new instance in the editor will fill it in with your new rules. In the line #15 the newly edited Rule Set is written (serialized) to an XML file with WorkflowMarkupSerializer.

The step #2 is implemented in the LoadRules function:

   1: public static RuleSet LoadRules(string rulesFileName)
   2: {
   3:     if (File.Exists(rulesFileName))
   4:     {
   5:         FileStream fs = new FileStream(rulesFileName, FileMode.Open);
   6:         StreamReader sr = new StreamReader(fs);
   7:         string serializedRuleSet = sr.ReadToEnd();
   8:         WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
   9:         StringReader stringReader = new StringReader(serializedRuleSet);
  10:         XmlTextReader reader = new XmlTextReader(stringReader);
  11:         var ruleSet = serializer.Deserialize(reader) as RuleSet;
  12:         fs.Close();
  14:         return ruleSet;
  15:     }
  16:     return null;
  17: }


Note that this function is doing a reverse Rule Set deserialization with the WorkflowMarkupSerializer and returning a Rule Set instance (if everything wen right).

The last, and the most important step #3, is executed in the Run-Rules CmdLet. It evaluates the rules against each and every PSObject in the command pipeline.

   1: // Validate the rules
   2: RuleValidation validation = new RuleValidation(typeof(PSCurrentItem), null);
   3: ruleSet.Validate(validation);
   4: if (validation.Errors.Count != 0)
   5: {
   6:     foreach (ValidationError error in validation.Errors)
   7:         WriteWarning(string.Format("Validation Error: {0}", error.ErrorText));
   8: }
   9: if (validation.Errors.Count != 0)
  10:     return;
  12: ...
  14: var psObject = new PSCurrentItem() { CurrentItem = this.CurrentItem, Runtime = this };
  16: // Execute the rules against the object
  17: RuleExecution execution = new RuleExecution(validation, psObject);
  18: ruleSet.Execute(execution);
  20: if (! psObject.StopProcessing)
  21:     WriteObject(CurrentItem);

First the rule set is validated against the target type (lines #2-3), the same type used while creating the rule set in the first time (line #4 in ShowRulesDialog). Then the rules are applied to the managed object (lines #17-18). The rules can modify the object which can change the flow of the logic. In line #20 the code checks if the StopProcesing flag was set or cleared which forces the object to be written back to the command pipe or omitted.

Hope this post was educational and showed how easy it is to use the Rule Set editor in your applications.


One Response to “PowerShell Rules Engine: How-To Technical Details”

  1. […] PowerShell Rules Engine: How-To Technical Details […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: