Invest in people before investing in tools

Il blog di Matteo Baglini
posts - 118, comments - 95, trackbacks - 697

[Spring.NET #23] Spring.Core, Introduzione al Validation Framework

Iniziamo a parlare del Validation Framework contenuto in Spring.NET, un framework molto completo e varsatile adatto a molti scenari. I motivi che hanno spinto il team di Spring.NET ha creare questo framework sono svariati, descritti dettagliatamente in qui e qui. Il più grande problema della maggior parte dei framework di validazione disponibili oggi è che sono troppo legati alla tecnologia di presentazione, come le stesse funzionalità di validazione fornite dal .NET Framework per ASP.NET e WinForm. Grazie a Spring.NET possiamo effettuare la validazione dei dati non più solo nel presentation layer ma in tutti i layer che compongono la nostra applicazione. Le caratteristiche del framework sono:

  • Permette la validazione di ogni tipo di oggetto, sia esso una Entity o uno UserControl.
  • Permette di utilizzare le solite regole di validazione sia in ASP.NET, WinForm piuttosto che nel service layer.
  • Permette la creazione di regole di validazione più o meno complesse combinabili fra loro.
  • Permette che la validazione venga eseguita solo con il verificarsi di una condizione.

Per impostare le regole di validazione, come per buona parte delle funzionalità di Spring.NET, possiamo utilizzare le API direttamente da codice oppure
tramite il file di configurazione richiamabili in seguito tramite l' ApplicationContext . Come per gli altri casi viene consigliato l'utilizzo del file XML in modo da poter cambiare il funzionamento del programma senza ricompilare il codice. I tag XML del Validation Framework sono definiti utilizzando un nuovo namespace. Come dicevo inizialmente il Validation Framework è molto vasto quindi dividerò l'argomento su più post, comincieremo creando un insieme di regole di validazione per una nostra entity e man mano spiegherò in dettagio i vari nodi della configurazione e l'integrazione con i vari toolkit grafici con dei post successivi. Cominciamo! Creiamo come di consueto una Console Application, implementiamo un piccolo Domain Model aggiungendo le classi AddressInfo e Person:

   1:  using System;
   2:   
   3:  namespace SpringSeries.Core.Validation {
   4:      public class AddressInfo {
   5:          private string _address = String.Empty;
   6:          public string Address {
   7:              get { return _address; }
   8:              set { _address = value; }
   9:          }
  10:   
  11:          private string _city = String.Empty;
  12:          public string City {
  13:              get { return _city; }
  14:              set { _city = value; }
  15:          }
  16:   
  17:          private string _postalCode = String.Empty;
  18:          public string PostalCode {
  19:              get { return _postalCode; }
  20:              set { _postalCode = value; }
  21:          }
  22:   
  23:          public override string ToString() {
  24:              return String.Format("Address:{0} City:{1} PostalCode:{2}", Address, City, PostalCode);
  25:          }
  26:      }
  27:  }
   1:  using System;
   2:   
   3:  namespace SpringSeries.Core.Validation {
   4:      public class Person {
   5:          private int _id = 0;
   6:          public int Id {
   7:              get { return _id; }
   8:          }
   9:   
  10:          private string _firstName = String.Empty;
  11:          public string FirstName {
  12:              get { return _firstName; }
  13:              set { _firstName = value; }
  14:          }
  15:   
  16:          private string _lastName = String.Empty;
  17:          public string LastName {
  18:              get { return _lastName; }
  19:              set { _lastName = value; }
  20:          }
  21:   
  22:          private DateTime _dateOfBirth = DateTime.MinValue;
  23:          public DateTime DateOfBirth {
  24:              get { return _dateOfBirth; }
  25:              set { _dateOfBirth = value; }
  26:          }
  27:   
  28:          private AddressInfo _addressInfo = new AddressInfo();
  29:          public AddressInfo AddressInfo {
  30:              get { return _addressInfo; }
  31:              set { _addressInfo = value; }
  32:          }
  33:   
  34:          public Person(int id) {
  35:              _id = id;
  36:          }
  37:   
  38:          public override string ToString() {
  39:              return String.Format("ID:{0} First Name:{1} Last Name:{2}", Id, FirstName, LastName) + " " + AddressInfo.ToString();
  40:          }
  41:      }
  42:  }

per essere valida la nostra entity Person deve avere imostate le property FirstName e DateOfBirth, inoltre se impostiamo la property AddressInfo.Address diventano obbligatorie anche le property AddressInfo.City e AddressInfo.PostalCode, quindi proseguiamo aggiungendo il file App.config e definendo la regola di validazione con la seguente configurazione:

<objects xmlns="http://www.springframework.net"          
xmlns
:v="http://www.springframework.net/validation">
<v:group id="PersonValidator">
<v:required id="PersonFirstNameValidator" test="FirstName" />
<v:condition id="PersonDateOfBirthValidator" test="DateOfBirth != DateTime.MinValue" />
<
v:ref name="AddressInfoValidator" />
</v:group>
<v:group id="AddressInfoValidator">
<v:required id="CityValidator" test="AddressInfo.City" when="AddressInfo.Address!=String.Empty" />
<v:required id="CapValidator" test="AddressInfo.PostalCode" when="AddressInfo.Address!=String.Empty" />
</
v:group>
</objects>

i tag contenuti in questo snippet XML sono abbastanza esplicativi, leggendoli notiamo che ogni regola di validazione può essere composta, utilizzando in questo caso il tag group, oppure singola utilizzando direttamente uno dei tag di validazione come per esempio required. Continuiamo notando che tramite l'attributo when indichiamo la condizione che farà applicare la regola e che tutte le regole hanno l'attributo id, utilizzabile per referenziarle fra loro. Un fattore degno di nota è che all'interno dei tag test e when indichiamo espressioni utilizzando il versatile e potente Expression Language di Spring.NET. In fine nel metodo Main istanziamo e processiamo diverse "versioni" di Person:

   1:  using System;
   2:  using Spring.Context;
   3:  using Spring.Context.Support;
   4:  using Spring.Validation;
   5:   
   6:  namespace SpringSeries.Core.Validation {
   7:      class Program {
   8:          static void Main(string[] args) {
   9:              IApplicationContext _context = ContextRegistry.GetContext();
  10:   
  11:              Person _p01 = new Person(1);
  12:              _p01.FirstName = "Matteo";
  13:              _p01.LastName = "Baglini";
  14:              _p01.DateOfBirth = new DateTime(1982, 11, 8);
  15:   
  16:              Person _p02 = new Person(2);
  17:              _p02.LastName = "Baglini";
  18:              _p02.DateOfBirth = new DateTime(1982, 11, 8);
  19:   
  20:              Person _p03 = new Person(3);
  21:              _p03.FirstName = "Matteo";
  22:              _p03.LastName = "Baglini";
  23:   
  24:              Person _p04 = new Person(4);
  25:              _p04.FirstName = "Matteo";
  26:              _p04.LastName = "Baglini";
  27:              _p04.DateOfBirth = new DateTime(1982, 11, 8);
  28:              _p04.AddressInfo.Address = "Via dei Sassi Sgonfi";
  29:   
  30:              Person _p05 = new Person(5);
  31:              _p05.FirstName = "Matteo";
  32:              _p05.LastName = "Baglini";
  33:              _p05.DateOfBirth = new DateTime(1982, 11, 8);
  34:              _p05.AddressInfo.Address = "Via dei Sassi Sgonfi";
  35:              _p05.AddressInfo.City = "Livorno";
  36:              _p05.AddressInfo.PostalCode = "57100";
  37:   
  38:              IValidator _validator = (IValidator)_context.GetObject("PersonValidator");
  39:   
  40:              Console.WriteLine(_p01.ToString());
  41:              Console.WriteLine("Is Valid? {0}", _validator.Validate(_p01, null));
  42:              Console.WriteLine();
  43:              Console.WriteLine(_p02.ToString());
  44:              Console.WriteLine("Is Valid? {0}", _validator.Validate(_p02, null));
  45:              Console.WriteLine();
  46:              Console.WriteLine(_p03.ToString());
  47:              Console.WriteLine("Is Valid? {0}", _validator.Validate(_p03, null));
  48:              Console.WriteLine();
  49:              Console.WriteLine(_p04.ToString());
  50:              Console.WriteLine("Is Valid? {0}", _validator.Validate(_p04, null));
  51:              Console.WriteLine();
  52:              Console.WriteLine(_p05.ToString());
  53:              Console.WriteLine("Is Valid? {0}", _validator.Validate(_p05, null));
  54:   
  55:              Console.Read();
  56:          }
  57:      }
  58:  }

come vediamo basta richiedere all'ApplicationContext, utilizzando l'id, il nostro validator e richiamare il suo metodo Validate indicando la nostra entity. Il secondo paremetro di questo metodo verrà affrontato nei futuri post, al momento non ci serve quindi passiamo il valore null.

Technorati Tag:

Print | posted on mercoledì 12 dicembre 2007 22:43 | Filed Under [ .NET OpenSource Spring.NET ]

Powered by:
Powered By Subtext Powered By ASP.NET