Home Page Home Page Tips & Tricks Come riempire una classe tipizzata usando la Reflection

Come riempire una classe tipizzata usando la Reflection


Quando usiamo le classi tipizzate per rappresentare le nostre entità di Business spesso mappiamo queste classi con le tabelle presenti nel nostro Database.

Esempio una tabella utente simile a questa:



La rappresentiamo come entità in questo modo

Codice .NET n°1
  #region fields
private Int32 _idUtente;
private string _cognome;
private string _nome;
private DateTime _dataNascita;
private string _indirizzo;
private string _posizione;
#endregion

#region properties
public Int32 IdUtente
{
get { return _idUtente; }
set { _idUtente = value; }
}
public string Cognome
{
get { return _cognome; }
set { _cognome = value; }
}
public string Nome
{
get { return _nome; }
set { _nome = value; }
}
public DateTime DataNascita
{
get { return _dataNascita; }
set { _dataNascita = value; }
}
public string Indirizzo
{
get { return _indirizzo; }
set { _indirizzo = value; }
}
public string Posizione
{
get { return _posizione; }
set { _posizione = value; }
}
#endregion


Per caricare questa entità usiamo un DataReader sia per recuperare il singolo record che una lista.

Per caricare tutte le proprietà dell’entità (la nostra classe tipizzata) di solito dobbiamo richiamare tutti i nomi dei campi che mappano la nostra entità. Capite bene che se sono parecchi campi diventa un po’ noioso ma indispensabile anche perché bisogna effettuare il giusto casting.

Esempio:

Codice .NET n°2
if(reader["Cognome"] != DBNull.Value)
{
this.Cognome = reader["Cognome"].ToString();

}


O ancora meglio usando i metodi DataReader.GetOrdinal e i singoli Get in base al tipo restituito.

Se invece non vogliamo scrivere una istruzione per ogni campo possiamo utilizzare la Reflection in questo modo:

ci definiamo una classe Utils così che può essere richiamata da tutte le nostre entità e poi creiamo un metodo statico SetFields:

Codice .NET n°3
using System.Data.SqlClient;
using System.Reflection;
public class Utils
{
public static object SetFields(object item, SqlDataReader reader)
{
PropertyInfo[] listProperty;
Type _type = item.GetType();
listProperty = _type.GetProperties();
foreach (PropertyInfo singleProperty in listProperty)
{
singleProperty.SetValue(item, reader[singleProperty.Name], null);
}

return item;
}
}//endclass


Analizziamo il codice:
Come parametri passiamo un object item che sarà la nostra classe e un DataReader che in questo esempio usa il provider SQL ma può essere anche un altro senza problemi.
Definiamo un' array di Proprietà con l'istruzione:

PropertyInfo[] listProperty;

poi come abbiamo visto in altri articoli sulla Reflection dobbiamo impostare il Type sul quale lavorare e nel nostro caso sarà:

Type _type = item.GetType();

Poi recuperiamo tutte le proprietà dell'oggetto:

listProperty = _type.GetProperties();

Poi eseguiamo un ciclo sull'array e settiamo la proprietà con il metodo SetValue:

Codice .NET n°4
foreach (PropertyInfo singleProperty in listProperty 
{
singleProperty.SetValue(item, reader[singleProperty.Name], null);
}


Come vedete con la proprietà Name andiamo a recupera esattamente il campo e quindi c’è un mapping 1 a 1 tra campo e proprietà e in automatico viene fatto il casting all’oggetto recuperato.

Infine nella nostra classe utente creiamo per esempio un metodo Get così fatto

Codice .NET n°5
public Utente Get() 
{
//Recupero il DataReader dal mio layer DAL

using(SqlDataReader reader = Dal.GetDataReader("GetUtente"))
{
while(reader.Read())
{
Utente _utente = Utils.SetFields(this, reader);
return _utente;
}
}

}


Quindi come potete vedere con un solo metodo e poche righe di codice possiamo aumentare di molto la produttività delle nostre classi tipizzate.

Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5