[Reflection] Come impostare ecc... con correzione apportata su suggerimento di Matteo

Mi sono ritrovato a dover sviluppare del codice che in base all'opportuna configurazione presente in un DB (ma potrebbe essere anche un .config...) imposta le proprietà di un dato oggetto.

La Reflection (System.Reflection) è la soluzione, e a parte la non sempre ampia documentazione, è pure una soluzione semplice.

L'esempio che ho sviluppato prevede l'esistenza di una tabella di struttura simile a quella di una sezione appSettings di un file .config: un campo Section (varchar), Key (varchar), un campo Value (varchar) e in più un campo Type (varchar). Nel campo Section ho impostato il nome del tipo di cui creerò l'istanza, nel campo Key c'è il nome della proprietà, nel campo Value il valore che la proprietà deve assumere e nel campo Type il Type della proprietà (es. System.String, System.Int32, ecc.).

La prima cosa di cui si ha bisogno è un riferimento all'assembly che contiene la definizione del tipo che vogliamo istanziare: la classe [Assembly] dispone di un metodo shared (static in C#) che passando il nome dell'assembly restituisce un oggetto di tipo Assembly

Dim _assembly As [Assembly] = [Assembly].LoadFrom("Lanny.Assembly.dll")

A questo punto devo reperire le informazioni circa il tipo presente nell'assembly

Dim _myType As [Type] = _assembly.GetType("MioNamespace.MioTipo")

Avendo questi riferimenti sono pronto a scorrere il contenuto della tabella e impostare le proprietà dell'oggetto MioOggetto di tipo MioTipo (Dim MiaClasse as New MioTipo); nel mio caso scorro un SQLDataReader, ma come ho detto in precedenza può essere qualunque cosa...

With MySQLDataReader

    Dim _myPorpertyInfo As PropertyInfo

    Do While .Read = True

        _myPropertyInfo = _myType.GetProperty(.Item("Key"))

        _myPropertyInfo.SetValue(MioOggetto, .Item("Value"), Nothing)

    Loop

End With

Se tutte le proprietà di MioTipo fossero di tipo System.String avremmo già finito, però se così non fosse bisogna trovare il modo di convertirle nel tipo giusto. Sfrutto la Reflection per ottenere un riferimento all'assembly mscorlib.dll (il Core del .NET Framework per intenderci, dove risiedono il namespace System e tutti i tipi del Framework); per evitare di andare a scrivere da qualche parte il percorso di installazione del Framework necessario per utilizzare [Assembly].LoadFrom() nel caso in cui l'assembly specificato non sia nell'application path, sfrutto un altro metodo shared (static in C#) del tipo [Assembly]: GetAssembly(value as System.Type).

'Questa correzione è stata apportata su suggerimento di Matteo: grazie 1000!

'Dim _SystemAssembly As [Assembly] = [Assembly].GetAssembly(GetType(String))

In pratica richiedo di referenziare l'assembly dove è definito il tipo String (cioé il mio mscorlib.dll)

Fatto ciò modifico il loop di prima come segue

 With MySQLDataReader

    Dim _myPorpertyInfo As PropertyInfo

    Do While .Read = True

        _myPropertyInfo = _myType.GetProperty(.Item("Key"))

          Dim _val As New Object

          _val = Convert.ChangeType(.Item("Value"), _myPropertyInfo.PropertyType) 'Vedi commento sopra

'_SystemAssembly.GetType(.Item("Type")))

        _myPropertyInfo.SetValue(MioOggetto, _val, Nothing)

    Loop

End With

 

Print | posted @ giovedì 24 agosto 2006 12:46

Comments have been closed on this topic.