#define _USE_FACTORY_
using System;
using System.Data;
using System.Reflection;
using System.Collections;
using System.Data.SqlClient;
namespace CSharpLab
{
#region IStringIndexableData
public interface IStringIndexableData
{
object this[string name]{get;}
}
#endregion
#region StringIndexableWrapper
///
/// Wrapper per oggetti che si possono indicizzare con stringhe
///
public class StringIndexableWrapper: IStringIndexableData
{
//definisco la firma dell'indexer per stringa
delegate object StringIndexerHandler(string index);
//definisco una cache dove salverò gli indexer per i vari tipi di oggetti
//in modo da evitare la fase di discovery via reflection se già eseguita
readonly static Hashtable indexersCache = new Hashtable();
//handler all'indexer
StringIndexerHandler indexerHandler;
#region Constructors
public StringIndexableWrapper(object stringIndexableObject)
{
//Ho già il methodinfo dell'indexer?
Type stringIndexableObjectType = stringIndexableObject.GetType();
MethodInfo indexerMethod = (MethodInfo) indexersCache[stringIndexableObjectType];
if(indexerMethod == null)
{
//Fase di discovery...
#region Finding string indexer
foreach(MemberInfo m in stringIndexableObjectType.GetDefaultMembers())
{
if(m is PropertyInfo)
{
PropertyInfo p = (PropertyInfo)m;
ParameterInfo[] parameters = p.GetIndexParameters();
if(parameters.Length == 1)
{
ParameterInfo indexParam = parameters[0];
if(indexParam.ParameterType == typeof(string))
{
indexerMethod = p.GetGetMethod();
break;
}
}
}
}
#endregion
//l'oggetto non è indicizzabile per stringa
if(indexerMethod == null)
throw new ArgumentException("Object is not string indexable.", "stringIndexableObject");
//salvo l'indexer nella cache
indexersCache[stringIndexableObjectType] = indexerMethod;
}
//Costruisco handler all'indexer.
//Perchè l'overload che accetta il methodInfo è valido solo per i metodi statici?
//Devo necessariamente usare overload che usa nome del metodo anche se conosco methodInfo?
indexerHandler =
(StringIndexerHandler)Delegate.CreateDelegate(
typeof(StringIndexerHandler),
stringIndexableObject,
indexerMethod.Name);
}
#endregion
#region IStringIndexableData Members
public object this[string s]
{
get
{
return indexerHandler(s);
}
}
#endregion
}
#endregion
#region StringIndexableDataFactory
public class StringIndexableDataRecord: IStringIndexableData
{
#region Fields
private IDataRecord dataRecord;
#endregion
#region Constructors
public StringIndexableDataRecord(IDataRecord dataRecord)
{
this.dataRecord = dataRecord;
}
#endregion
#region IStringIndexableData Members
public object this[string name]
{
get
{
return this.dataRecord[name];
}
}
#endregion
}
public class StringIndexableDataRow: IStringIndexableData
{
#region Fields
private DataRow dataRow;
#endregion
#region Constructors
public StringIndexableDataRow(DataRow dataRow)
{
this.dataRow = dataRow;
}
#endregion
#region IStringIndexableData Members
public object this[string name]
{
get
{
return this.dataRow[name];
}
}
#endregion
}
public class StringIndexableDataRowView: IStringIndexableData
{
#region Fields
private DataRowView dataRowView;
#endregion
#region Constructors
public StringIndexableDataRowView(DataRowView dataRowView)
{
this.dataRowView = dataRowView;
}
#endregion
#region IStringIndexableData Members
public object this[string name]
{
get
{
return this.dataRowView[name];
}
}
#endregion
}
public class StringIndexableDataFactory
{
#region CreateStringIndexableData
public static IStringIndexableData CreateStringIndexableData(IDataRecord record)
{
return new StringIndexableDataRecord(record);
}
public static IStringIndexableData CreateStringIndexableData(DataRow row)
{
return new StringIndexableDataRow(row);
}
public static IStringIndexableData CreateStringIndexableData(DataRowView row)
{
return new StringIndexableDataRowView(row);
}
#endregion
}
#endregion
public class IndexerTest
{
public static void DoTest()
{
string sql = "SELECT * FROM Customers";
using(SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;Data Source=(local)"))
{
connection.Open();
//... uso la datatable
SqlDataAdapter adp = new SqlDataAdapter(sql, connection);
DataTable dt = new DataTable();
adp.Fill(dt);
foreach(DataRow row in dt.Rows)
{
#if _USE_FACTORY_
IStringIndexableData si = StringIndexableDataFactory.CreateStringIndexableData(row);
#else
StringIndexableWrapper si = new StringIndexableWrapper(row);
#endif
Print(si);
}
//... uso la dataview
DataView view = dt.DefaultView;
foreach(DataRowView rowView in view)
{
#if _USE_FACTORY_
IStringIndexableData si = StringIndexableDataFactory.CreateStringIndexableData(rowView);
#else
StringIndexableWrapper si = new StringIndexableWrapper(rowView);
#endif
Print(si);
}
//... uso il datareader
SqlCommand cmd = new SqlCommand(sql, connection);
SqlDataReader r = cmd.ExecuteReader();
while(r.Read())
{
#if _USE_FACTORY_
IStringIndexableData si = StringIndexableDataFactory.CreateStringIndexableData(r);
#else
StringIndexableWrapper si = new StringIndexableWrapper(r);
#endif
Print(si);
}
}
}
private static void Print(IStringIndexableData si)
{
Console.WriteLine(si["CompanyName"]);
}
}
}
posted @ sabato 19 marzo 2005 19:42