Utilizzare l'editor di regole di WF per la validazione di oggetti custom

di Giuseppe Marchi, in Windows Workflow Foundation,

Nell'articolo dedicato alle regole e condizioni di Windows Workflow Foundation, abbiamo visto le grandi potenzialità del motore offerte dal framework WF in collaborazione con le attività condizionali (IfElse, While, ecc..) e con l'activity Policy. Allo stesso modo in cui possiamo sfruttare questi meccanismi all'interno di un workflow, abbiamo la possibilità di utilizzare un set di regole basate sulla struttura di una nostra entità custom e procedere alla validazione delle informazioni prelevate da una o più istanze della medesima classe.

Per la compilazione delle regole, WF ci mette a disposizione il medesimo editor che normalmente utilizziamo da Visual Studio. L'unica cosa che dobbiamo aggiungere è la creazione del file .rules, contenente il nostro RuleSet e i meccanismi per la lettura dello stesso.

Da notare che per utilizzare le classi utili al corretto funzionamento dell'engine di Workflow Foundation e dell'editor di regole e condizioni, dobbiamo aggiungere al nostro progetto le referenze ai namespace System.Workflow.Activities e System.Workflow.ComponentModel.

Come abbiamo accennato all'interno dell'approfondimento su regole e condizioni, tale file di regole non è altro che la serializzazione in XML di un oggetto di tipo RuleSet (scendendo sullo specifico, viene fatta una trasformazione utilizzando la sintassi XAML), operazione questa che viene fatta da Visual Studio in maniera del tutto invisibile all'utente; in questo caso, data l'assenza di un workflow a cui associare queste regole, dobbiamo scrivere due metodi custom, uno per la lettura e de-serializzazione del RuleSet e l'altro invece per serializzare le informazioni (eventualmente modificate) e riportarle sul file system.

private readonly WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
private string filepath = Path.Combine(Environment.CurrentDirectory, "regole.rules");
private RuleSet DeserializeRuleSet() {
  if (File.Exists(filepath)) {
    XmlTextReader reader = new XmlTextReader(filepath);
    object obj = serializer.Deserialize(reader);
    reader.Close();
    return obj as RuleSet;
  }
  return null;
}
private void SerializeRuleSet(RuleSet ruleSet) {
  StringBuilder xml = new StringBuilder();      
  StringWriter sw = new StringWriter(xml, CultureInfo.InvariantCulture);
  XmlTextWriter writer = new XmlTextWriter(sw);
  serializer.Serialize(writer, ruleSet);
  writer.Close();
  sw.Close();
  XmlDocument doc = new XmlDocument();
  doc.LoadXml(xml.ToString());
  File.Delete(filepath);
  doc.Save(filepath);
}

La serializzazione e de-serializzazione di un oggetto di tipo RuleSet, non viene fatta utilizzando le normali classi di serializzazione in XML fornite dal .NET framework, ma viene utilizzata una classe propria del framework Workflow Foundation denominata WorkflowMarkupSerializer, classe questa che serializza le informazioni in formato XAML e viene utilizzata dal motore di workflow e da Visual Studio stesso per la gestione dei file .xoml e .rules relativi ad un qualsiasi workflow.

Tramite queste due operazioni, possiamo così utilizzare l'editor di regole offerto da Workflow Foundation. Tale editor è rappresentato dalla classe RuleSetDialog: una finestra di dialogo stile Windows Form, in cui visualizzare le regole già presenti, modificarle o aggiungerle. Il punto di interesse sta alla creazione di una nuova istanza dell'editor, in quanto il costruttore di base vuole il tipo con cui procedere poi alla valutazione delle informazioni (nel nostro caso, utilizziamo una classe custom chiamata Order), questo per permettere all'utente di trovare le proprietà corrette all'interno dell'intellisense e per mantenere all'interno del RuleSet i corretti riferimenti a proprietà e metodi.
Oltre alla struttura sulla quale creare e valutare le varie regole, la classe RuleSetDialog necessita di un oggetto di tipo RuleSet per presentare a video le regole lette dal file .rules (se non sono presenti, il costruttore accetta anche un valore nullo).

RuleSet ruleSet = DeserializeRuleSet();
using (RuleSetDialog dialog = new RuleSetDialog(typeof(Order), null, ruleSet))
{
  if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  {
    ruleSet = dialog.RuleSet;
    SerializeRuleSet(ruleSet);          
  }
}

Ora abbiamo completato la nostra gestione personalizzata delle regole e del relativo file .rules; il codice che crea una nuova istanza dell'editor può essere benissimo inserito all'interno di un evento click su un bottone o richiamato da un menu, così facendo abbiamo la possibilità di arricchire i nostri progetti Windows Form o WPF, con tecniche di validazione dei dati parecchio avanzate e di facile utilizzo.

Manca quindi solo la validazione. Recuperando il RuleSet dal nostro file .rules ed istanziando due oggetti di tipo RuleValidation e RuleEngine, possiamo così procedere alla validazione delle informazioni inserite all'interno di una nuova istanza della classe Order (entità avente la struttura sulla quale ci siamo basati per la costruzione delle regole) e alla valutazione delle azioni effettuate.

RuleSet ruleSet = DeserializeRuleSet();
RuleValidation validation = new RuleValidation(typeof(Order), null);
RuleEngine engine = new RuleEngine(ruleSet, validation);
engine.Execute(o);

L'esempio allegato è banale, ma è importante notare che un sistema basato sulla validazione di regole offerta da Windows Workflow Foundation può risultare veramente molto potente, soprattutto pensando al fatto che possiamo evitare la scrittura massiccia di codice di validazione delle informazioni.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi