Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

campi & attributi

3 views
Skip to first unread message

marcodb

unread,
Jan 20, 2008, 3:56:38 PM1/20/08
to
Ciao,

Ho bisogno di un consiglio Architetturale --- nella domanda che segui non
date quindi il valore giusto(nel mondo .net) alle parole
attributo/proprietà/decorato/...ecc..ec.. in quanto sarebbero fuorvianti....
Mi serve appunto un consiglio su come gestire tali necessità attribuendo un
valore generale (in italiano) alle parole usate...

Devo realizzare delle classi che contengono una serie di campi(propietà)
prestabiliti:

Class MyClass

Field1 as string
field2 as int
field3 as MyTipe

End class

Ogni campo/proprietà deve poter essere "decorato" da alcune
proprieta/attributi che ne identificano un certo comportamento.

Per esempio

field1 potrebbe essere decorato con una (o più di queste proprietà)

1)required
2)required, default
3)required not default
4)fixedvalue
5)ignored
6)reserved
...
..
ecc
ecc.

In seguito,

A run-time ho bisogno di scoprire se quel campo è decorato da una u più di
tali proprieta e ottenerle.
Ed inoltre a seconda della proprietà voglio recuperare un valore specifico
che la rappresenta...

esempio :

scopro che field1 è di tipo required,default a questo punto voglio sapere
anche quale è il valore di default:

field1 ---> requireddefault ---> defaultvalue=4


grazie tante

Marco

Mauro Servienti [MVP]

unread,
Jan 20, 2008, 4:34:28 PM1/20/08
to
Ciao marcodb,

You wrote :


>
> field1 ---> requireddefault ---> defaultvalue=4
>

la risposta sono gli attributi e un po' di sana reflection, per gli
attributi custom ti basta realizzare una classe che deriva da Attribute
e il gioco è fatto.

Faccio io una domanda: stai pensando ad un sistema di validazione?

.m

--
Mauro Servienti
Microsoft MVP - Visual C# / MCP
http://mvp.support.microsoft.com
http://blogs.ugidotnet.org/topics
whynot [ at ] topics [ dot ] it


Matteo Migliore

unread,
Jan 20, 2008, 4:52:25 PM1/20/08
to
> Ho bisogno di un consiglio Architetturale --- nella domanda che segui non
> date quindi il valore giusto(nel mondo .net) alle parole
> attributo/proprietà/decorato/...ecc..ec.. in quanto sarebbero
> fuorvianti....
> Mi serve appunto un consiglio su come gestire tali necessità attribuendo
> un valore generale (in italiano) alle parole usate...


La spiegazione è piuttosto lunga.

In sostanza si applica il principio dell'Inversion Of Control,
per cui la validazione non si fa tramite attributi ed inoltre si delega la
validazione
ad una classe esterna, per non creare dipendenze.

Se il metodo che valida fosse definito internamente alla classe
e fosse basato su attributi, sarebbe necessario ricompilare
l'applicazione ogni volta che si cambia la logica di validazione.

In più si lega il concetto di valido alla definizione della classe,
rendendola difficilmente utilizzabile in scenari differenti.

Per una spiagazione più completa di questa metodologia
ti rimando a questo articolo:
http://martinfowler.com/articles/injection.html.

Dovrei inoltre implementare questo sistema in un'applicazione
open che stò sviluppando.

Se hai altri dubbi chiedi pure! :-).

Mi scuso per la lunghezza, ma con meno codice non sarebbe possibile
spiegare i concetti.

Qui l'esempio:
--------------------------------------------
''' <summary>
''' Represents a validable entity.
''' </summary>
Public Interface IValidableEntity
Function IsValid() As Boolean
End Interface

''' <summary>
''' Represents a validator.
''' </summary>
Public Interface IEntityValidator
Function IsValid(Of T)(ByVal item As Object) As Boolean
End Interface

''' <summary>
''' Represents a concrete hard coded validator.
''' </summary>
Public Class FooValidator
Implements IEntityValidator
#Region "IEntityValidator Members"
Public Function IsValid(Of T)(ByVal item As Object) As Boolean Implements
IEntityValidator.IsValid
If GetType(T) Is GetType(Person) Then
Dim person As Person = CType(item, Person)
Return ((Not String.IsNullOrEmpty(person.Name)))
Else
Throw New NotSupportedException()
End If
End Function
#End Region
End Class

''' <summary>
''' Returns a concrete validator using a particular logic.
''' </summary>
Public Class ValidatorFactory
Private Sub New()
End Sub
Public Shared Function GetValidator(Of T)() As IEntityValidator
If GetType(T) Is GetType(Person) Then
Return New FooValidator()
Else
Throw New NotSupportedException()
End If
End Function
End Class

''' <summary>
''' Represents a person.
''' </summary>
Public Class Person : Implements IValidableEntity
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property

Public Function IsValid() As Boolean Implements IValidableEntity.IsValid
Return ValidatorFactory.GetValidator(Of Person)().IsValid(Of Person)(Me)
End Function
End Class
--------------------------------------------

--
Matteo Migliore
Blog - http://blogs.ugidotnet.org/matteomigliore

Matteo Migliore

unread,
Jan 20, 2008, 4:55:06 PM1/20/08
to
> la risposta sono gli attributi e un po' di sana reflection, per gli
> attributi custom ti basta realizzare una classe che deriva da Attribute e
> il gioco è fatto.
>
> Faccio io una domanda: stai pensando ad un sistema di validazione?


Mauro, scusa la doppia risposta, ma l'avevo già pronta,
avevo dimenticato di inviarla :-P.

Ciao!!

marcodb

unread,
Jan 20, 2008, 5:16:42 PM1/20/08
to

> Faccio io una domanda: stai pensando ad un sistema di validazione?


non ho le idee chiare su cosa intendi....

mi ricordo che hanni fa circolava la Janky Validation....una sera quando ne
parlavano in macchina Janky e Lorenzo ...c'ero sentivo che ne parlavano ma
non ho mai capito di cosa si trattasse! centra qualcosa?

Comunque sia; se rispondessi : Sì! cosa hai da propormi?

ciao e grazie.

marco b

marcodb

unread,
Jan 20, 2008, 5:20:29 PM1/20/08
to
Grazie Matteo ora mi studio la tua risposta.....

marco b

"Matteo Migliore" <matteo.mi...@gmail.com> ha scritto nel messaggio
news:%23N18E76...@TK2MSFTNGP04.phx.gbl...

marcodb

unread,
Jan 20, 2008, 5:56:16 PM1/20/08
to
Premetto che non è ancora del tutto chiaro la necessità di tale sistema di
validazione.

comunque dal tuo esempio ho:

una intefaccia: IValidableEntity (implementata da person)
una intefaccia: IEntityValidator (implementata da FooValidator)
una classe: person
una classe: FooValidator
una classe:ValidatorFactory

Immagino che il client:

0)istanzi una classe person e chiami isvalid che richiama la
validatorfactory
1)la ValidatorFactory chiami GetValidator(passando il tipo necessario -
person in questo caso)
2)il metodo ritorna una FooValidator (che espone l'interfaccia
IEntityValidator e quindi il metodoIsValid)
3)a questo punto viene verificata la validità hard coded in FooValidator

Se ho capito la logica, ti chiedo comunque di darmene la motivazione di
questo "rigirio" in quanto non capisco la necessità.

In particolora la presenza di FooValidator e ValidatorFactory che entrambi
devono conoscere il tipo Person.

......

Tirnando al mio caso io ho necessità di valutare la validità non di una
intera classe ma solo dei suoi campi singolarmente.
E ogni campo lo devo distiguere da un'altro tramite un qualche sistema di
demarcazione

in quanto potrei avere 3 campi string che ovviamente si chiamano
diversamente ma uno lo voglio validare con una regola perche per esempio
deve essere una string di una lunghezza fissata
mentre l'altro campo deve essere una stringa di lunghezza arbitraria....o
ancora più difficile...deve poter avere un valore di default...


Cosa posso fare.?

grazie

ciao marco b


Mauro Servienti [MVP]

unread,
Jan 20, 2008, 11:46:44 PM1/20/08
to
Ciao marcodb,

You wrote :


>> Faccio io una domanda: stai pensando ad un sistema di validazione?
>

> Comunque sia; se rispondessi : Sì! cosa hai da propormi?
>

che io personalmente non condivido la scelta di design di piazzare le
regole per la validazione su una classe scolpendole nella pietra troppo
restrittivo, IMVHO.

> ciao e grazie.
>
> marco b

.m

Marco Bosco

unread,
Jan 21, 2008, 11:12:22 AM1/21/08
to

> che io personalmente non condivido la scelta di design di piazzare le
> regole per la validazione su una classe scolpendole nella pietra troppo
> restrittivo, IMVHO.
>

Puoi spiegarti meglio perfavore non ti seguo in quanto non conosco queste
metodologie.
Dopo alcune letture sono arrivato a Spring.Net , ritieni che sia una
soluzione al mio problema?
Solo che dovre implementare un framework di cui non conosco niente.
Esiste un sistema per risolvere il mio problema in modo elegante senza
andare a complicare le cose?

ciao grazie.

marco


Matteo Migliore

unread,
Jan 21, 2008, 11:45:36 AM1/21/08
to
> Puoi spiegarti meglio perfavore non ti seguo in quanto non conosco queste
> metodologie.
> Dopo alcune letture sono arrivato a Spring.Net , ritieni che sia una
> soluzione al mio problema?

Sprint.NET è un framework che tra le altre cose
fornisce supporto al pattern Inversion Of Control (IoC).

Non è necessario però adottare un toolkit esterno
per risolvere problemi semplici. E' utile in applicazioni
che gestiscono pesantemente le funzionalità tramite
file di configurazione.

Nell'esempio che ho fatto, la classe ValidatorFactory
restituisce la classe concreta che esegue la validazione
istanziandola direttamente. E' ovviamente possibile invece
scrivere in un file di configurazione (app.config) quale classe
istanziare per eseguire la validazione per ogni tipo gestito.

In questo modo è possibile sostituire la classe che esegue
la validazione semplicemente modificando il file di configurazione,
e cambiare eventualmente la logica di validazione.

E' inoltre possibile scrivere un file XML di mapping
(simile ai file hbm.xml di NHibernate) in cui definire
per ogni property i validatori da applicare anzichè
cablarli nel codice della classe.

Esempio:
----------------------------------------
<validableEntity name="Person">
<property name="Name">
<validator type="RequiredValidator" value="true" />
<validator type="MinLenghtValidator" value="10" />
</property>
<property name="Age">
<validator type="RequiredValidator" value="false" />
<validator type="MinDateValidator" value="01/01/1980" />
</property>
</validableEntity>
----------------------------------------

Quindi la classe FooValidator potrebbe leggere queste
informazioni dal file XML e istanziare i validatori
per ogni property e richiamarli.

> Solo che dovre implementare un framework di cui non conosco niente.
> Esiste un sistema per risolvere il mio problema in modo elegante senza
> andare a complicare le cose?

Puoi partire dall'esempio che ho fatto.
Una volta capito quello puoi passare a qualcosa di
più sofisticato.

> ciao grazie.

Prego! ;-)

--
Matteo Migliore
Blog: http://blogs.ugidotnet.org/matteomigliore

marcodb

unread,
Jan 21, 2008, 1:58:59 PM1/21/08
to

>
> Esempio:
> ----------------------------------------
> <validableEntity name="Person">
> <property name="Name">
> <validator type="RequiredValidator" value="true" />
> <validator type="MinLenghtValidator" value="10" />
> </property>
> <property name="Age">
> <validator type="RequiredValidator" value="false" />
> <validator type="MinDateValidator" value="01/01/1980" />
> </property>
> </validableEntity>
> ----------------------------------------
>
> Quindi la classe FooValidator potrebbe leggere queste
> informazioni dal file XML e istanziare i validatori
> per ogni property e richiamarli.
>


Sei sicuro che dovrebbe essere FooValidator a doverlo fare?
A me sembra più logico che sia ValidatorFactory a recupera il file xml ed in
base al tipo chiamante passarre l'ooportuno foovalidator

dove sbaglio?

ciao

grazie.

m b


Matteo Migliore

unread,
Jan 21, 2008, 5:41:25 PM1/21/08
to
> Sei sicuro che dovrebbe essere FooValidator a doverlo fare?

Sě, abbastanza sicuro :-D.

> A me sembra piů logico che sia ValidatorFactory a recupera il file xml ed

> in base al tipo chiamante passarre l'ooportuno foovalidator
>
> dove sbaglio?

FooValidator potrebbe essere rinominato in
XmlMappingValidator, poi potresti avere un HardCodeValidator
etc... ValidatorFactory č solamente la classe che ritorna
il validator concreto.

Qui ho pubblicato una semplice solution,
forse si capisce meglio:
http://www.codeplex.com/ValidationInverse

La solution si trova sotto la sezione "Source Code".

Purtroppo č in C#, ma online si trovano
decine di tool per la conversione.

marcodb

unread,
Jan 21, 2008, 6:33:56 PM1/21/08
to
domani ci studio e poi ti faccio sapere.....

grazie per adesso.

Marco B

"Matteo Migliore" <matteo.mi...@gmail.com> ha scritto nel messaggio

news:%2398lE7H...@TK2MSFTNGP06.phx.gbl...

marcodb

unread,
Jan 22, 2008, 2:13:07 PM1/22/08
to
Matteo ho scaricato la soluzione (grazie) e lo eseguita passo passo tre
volte....
mi sono disegnato anche uno schema...ma non ho capito ancora come funziona.

Ti chiedo cortesemente di darmi una spiegazione a voce (scritta in italiano)
delle fasi e soprattutto del perchè
infatti nonostante capisca le chiamate e tutto ciò che succede mi sfugge il
significato di tutti quei passaggi e chiamate di interfaccia.

grazie

ciao

marco


Matteo Migliore

unread,
Jan 22, 2008, 3:21:54 PM1/22/08
to

Ci riprovo :-).

La classe statica ValidationFactory restituisce una factory
che restituisce un validatore concreto (HardCodedValidator o XmlValidator).

Il validator concreto può essere selezionato specificandolo dal
file di configurazione. La classe Person che implementa
il metodo di validazione IsValid *non* conosce la classe
concreta che si occuperà della validazione.

Questo consente di cambiare il metodo di validazione
senza modificare la classe Person, consentendo
inoltre di cambiare la logica di validazione
a seconda dello scenario o del contesto di utilizzo
di Person.

E' più chiaro?

Se hai pazienza implemento anche una versione
che consente di specificare i validatori
via XML.

> grazie

Mauro Servienti [MVP]

unread,
Jan 23, 2008, 3:24:06 AM1/23/08
to
Ciao marcodb,

You wrote :


> Ti chiedo cortesemente di darmi una spiegazione a voce (scritta in italiano)
> delle fasi e soprattutto del perchè
> infatti nonostante capisca le chiamate e tutto ciò che succede mi sfugge il
> significato di tutti quei passaggi e chiamate di interfaccia.
>

marco nonostante l'esempio di Matteo sia più che corretto e decisamente
semplice se non hai mai avuto necessità di IoC (Inversion of Control) e
non hai idea di filosoficamente cosa sia anche quell'esempio è uno
scoglio difficilmente superabile, soprattutto perchè mi sembra che il
tuo scopo sia giustamente quello di capire e non solo pedissequamente
applicare. Detto questo, vediamo di capire il problema:

Il problema in qualsiasi contesto (non solo la programmazione, anche se
per noi è particolarmente sentito) sono le dipendenze:

ComponenteA usa ComponenteB, se cambi B molto probabilmente A si
scassa... e questo è male.

class ComponentA
{
void Foo()
{
ComponentB obj = new ComponentB();
obj.Execute();
}
}

class ComponentB
{
public void Execute()
{
//Do something...
}
}

Ma la domanda è A ha effettivamente bisogno di conoscere B? No, in
realtà gli basterebbe sapere che B è in grado di fare qualcosa non
tanto di conoscere B, possiamo quindi alzarci di un livello e dire che
A deve conoscere cosa fa B e non necessariamente B

ComponenteA conosce la "firma" (che descrive cosa fa B) di B e non
direttamente B

a questo punto l'unico legame è la *firma*, per il fx questo si traduce
in una interfaccia:

class ComponentA
{
void Foo()
{
*IComponentB* obj = new ComponentB();
obj.Execute();
}
}

interface IComponentB
{
void Execute();
}

class ComponentB : IComponentB
{
public void Execute()
{
//Do something...
}
}

come si vede ComponentA non deve necessariamente conoscere B ma gli
basterebbe conoscere la sola interfaccia, ma come fare per eliminare
quella fastidiosissima riga di codice:

IComponentB obj = new ComponentB();

in cui c'è ancora una dipendenza evidentissima?

Abbiamo bisogno di un terzo attore che sia in grado di risolvere la
dipendenza: Inverson of Control per l'appunto...

class ComponentA
{
void Foo()
{
IComponentB obj = ComponentProvider.Resolve<IComponentB>();
obj.Execute();
}
}

La parte che fa la magia è questa:
IComponentB obj = ComponentProvider.Resolve<IComponentB>();

il componente A in questo caso non sa più nulla del componente B,
figoso non trovi :-D

Il ComponentProvider è quello che fa la magia, data l'interfaccia che
vogliamo legge da un file di configurazione cosa ci deve ritornare e ci
ritorna l'istanza concreta di B, in questo caso, ma noi non lo
sappiamo... :-D

Come realizzare il ComponentProvider? non lo realizziamo ma ci
affidiamo a un framework che lo fa per noi, IMVHO il migliore in questo
momento è Spring.NET ma è decisamente complesso e la curva di
apprendimento iniziale abbastanza ripida, quindi per partire meglio
"Castle Windsor" che fa qualcosa meno ma è più immediato. Sul sito c'è
anche un breve tutorial che ti introduce ad IoC.

http://www.castleproject.org/container/index.html
http://www.castleproject.org/container/gettingstarted/part1/index.html

Marco Bosco

unread,
Jan 23, 2008, 8:05:18 AM1/23/08
to
> ComponentProvider.Resolve(); obj.Execute(); } }

> La parte che fa la magia è questa: IComponentB obj =
> ComponentProvider.Resolve();

> il componente A in questo caso non sa più nulla del componente B, figoso
> non trovi :-D
> Il ComponentProvider è quello che fa la magia, data l'interfaccia che
> vogliamo legge da un file di configurazione cosa ci deve ritornare e ci
> ritorna l'istanza concreta di B, in questo caso, ma noi non lo sappiamo...
> :-D
> Come realizzare il ComponentProvider? non lo realizziamo ma ci affidiamo a
> un framework che lo fa per noi, IMVHO il migliore in questo momento è
> Spring.NET ma è decisamente complesso e la curva di apprendimento iniziale
> abbastanza ripida, quindi per partire meglio "Castle Windsor" che fa
> qualcosa meno ma è più immediato. Sul sito c'è anche un breve tutorial che
> ti introduce ad IoC.
> http://www.castleproject.org/container/index.html
> http://www.castleproject.org/container/gettingstarted/part1/index.html

Mauro,Matteo

ritengo che la tua spiegazione sia stata molto chiara.
Penso di aver capito.

A questo punto vi chiedo per favore, di crearmi un mapping degli oggetti tra
quest'ultima spiegazione e gli oggetti della solution che mi ha proposto
Matteo in modo che possa capire meglio la solution pubblicata su UGI da
Matteo.

Inoltre: è possibile creare una semplice implementazione del
ComponentProvider senza andare a "tirare fuori" Spring.NET o Castle Windsor?

grazie tante ad entrambi!

ciao
mb


Matteo Migliore

unread,
Jan 23, 2008, 8:37:40 AM1/23/08
to
> ritengo che la tua spiegazione sia stata molto chiara.
> Penso di aver capito.
>
> A questo punto vi chiedo per favore, di crearmi un mapping degli oggetti
> tra quest'ultima spiegazione e gli oggetti della solution che mi ha
> proposto Matteo in modo che possa capire meglio la solution pubblicata su
> UGI da Matteo.

La solution comunque è pubblicata su CodePlex, non su UGI.

> Inoltre: è possibile creare una semplice implementazione del
> ComponentProvider senza andare a "tirare fuori" Spring.NET o Castle
> Windsor?

Sì, è esattamente quanto implementanto
attraverso la ValidationFactory, che restituisce
il provider concreto via Reflection, senza usare
toolkit aggiuntivi.

Nella spiegazione di Mauro, riferendomi alla mia solution:
- ComponentA: è la classe Person che necessità di un metodo per essere
validata
- ComponentB: ad esempio (ma è solo una delle possibilità) è la classe
HardCodedValidator
che viene delegata da ValidationFactory, tramite file di configurazione, ad
essere
la classe concreta che fornisce uno dei possibili metodi di validazione

Spero sia più chiaro.

> grazie tante ad entrambi!

Marco Bosco

unread,
Jan 23, 2008, 10:26:29 AM1/23/08
to
Nell'esempio di Matteo c'era:

1)Interface IValidableEntity
2)Interface IEntityValidator
3)FooValidator (Implements IEntityValidator)
4)Class ValidatorFactory
5)Class Person (Implements IValidableEntity)

Qualcosa mi sfugge, c'č un'oggeto in piů

nella spiegazione di Mauro ci sono 4 oggetti
1)A (person)
2)B (FooValidator)
3)ICombonentB (che č un'interfaccia-implementata da b)
4)IcomponentProvider

Qual'č l'oggetto in piů ....e perche? a cosa serve?

ciao grazie.

MB


Matteo Migliore

unread,
Jan 23, 2008, 10:45:17 AM1/23/08
to

> Nell'esempio di Matteo c'era:
>
> 1)Interface IValidableEntity
> 2)Interface IEntityValidator
> 3)FooValidator (Implements IEntityValidator)
> 4)Class ValidatorFactory
> 5)Class Person (Implements IValidableEntity)
>
> Qualcosa mi sfugge, c'è un'oggeto in più

>
> nella spiegazione di Mauro ci sono 4 oggetti
> 1)A (person)
> 2)B (FooValidator)
> 3)ICombonentB (che è un'interfaccia-implementata da b)
> 4)IcomponentProvider
>
> Qual'è l'oggetto in più ....e perche? a cosa serve?

Eh va beh, ma così non vale :-).

Stai confrontanto banane con mele :-)

- Person implementa IValidableEntity,
- I validatori concreti devono implementare IEntityValidator
- ValidationFactory è la factory che maschera il validatore concreto

Una domanda specifica? :-)

> ciao grazie.

Mauro Servienti [MVP]

unread,
Jan 23, 2008, 10:59:53 AM1/23/08
to
Ciao Marco,

You wrote :
> Qual'è l'oggetto in più ....e perche? a cosa serve?
>

smetti di cercare di capire la cosa in maniera così maccheronica, non
serve a nulla.
Guarda il tutorial di Castle che ti ho postato, vale anche se poi non
usi castle perchè ti spiega i concetti di base.

Inoltre fai un po' di prove, come ti fa fare il tutorial, in un
ambiente "protetto" che sia il più semplice possibile.

0 new messages