37 messaggi dal 08 agosto 2008
Nel mio dominio ho un oggetto (Attività) che l'utente dovrebbe essere in grado di dichiarare bloccato disabilitandone così le modifiche.

L'Oggetto ha queste proprietà:
-idAttivita
-descrizioneAttivita
-bloccata
- circa altri 20 campi

io vorrei che le proprietà dell'oggetto non fossero modificabili nei casi in cui "bloccata" fosse true.

Idea 1)
mettere il controllo su tutti i metodi Set delle mie proprietà ma replicare la logica 20 volte non mi entusiasma

Idea 2)
dichiarare tutti i Set private e creare un metodo ModificaAttivita(Attivita valoreAttuale, Attivita valoreDesiderato), solo che ho un un costruttore fluent per la classe che prevede la creazione da parte dell'oggetto stesso del campo idAttivita (leggendo il valore massimo presente in db e aggiungendo 1) e di fatto sarei costretto a creare un oggetto nuovo e non una copia del vecchio con delle proprietà modificate (ovvero volendo modificare la descrizione dell'attivita "1-Descrizione" sarei costretto a passargli un oggetto "2-DescrizioneModificata" il che non mi pare molto corretto.

Idea3)
dichiarare tutti i Set private e creare un metodo ModificaAttivita(Attivita valoreAttuale, Idcitionary<EnumProprietaAttivita, object> valori)
ma così facendo con l'enum potrebbe arrivarmi qualsiasi cosa e perderei il controllo che la factory mi garantisce

Esiste un'altra strada o sono proprio costretto ad usare la prima?
Modificato da AdeptusAstartes il 05 settembre 2013 08.34 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,

AdeptusAstartes ha scritto:

replicare la logica 20 volte non mi entusiasma

Potresti usare PostSharp per evitare la ripetizione. Inserisci la logica in un aspetto e la applichi a tutte le proprietà. PostSharp fa compile-time weaving e ciò vuol dire che quella logica finirà nei setter delle proprietà proprio come se l'avessi inserita tu. Il vantaggio è aver evitato la ripetizione.
Prova a vedere l'esempio al paragrafo "Securing Fields and Properties"
http://www.postsharp.net/aspects/examples/security#title1
In questo caso applicano la logica al getter, anziché al setter.

In alternativa, leggo su StackOverflow che potresti far derivare la tua classe di entità da ContextBoundObject. Ma non l'ho mai provato e non ti so dare altri consigli su come usarlo.

ciao,
Moreno

Enjoy learning and just keep making
37 messaggi dal 08 agosto 2008
Idea interessante, ma anche questa mi entusiasma poco, diciamo che fino ad ora la cosa la gestivo a livello di interfaccia, ovvero se il campo bloccato era valorizzato disabilitavo il pulsante di modifica.

Nell'ottica del DDD stavo cercando di scrivere la logica direttamente nell'oggetto per renderla più evidente e testabile mentre con PS la logica dovrei metterla altrove.

Detto ciò davvero interessante questa possibilità di PS, così come quella della validazione compile-time
37 messaggi dal 08 agosto 2008
Affinando un pò la ricerca su google ho trovato questo esempio su http://stackoverflow.com/questions/6030936/is-there-a-way-to-intercept-setters-and-getters-in-c#answers-header:

public class Person
{
    private 
    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            // see how we can call a method below? or any code for that matter..
            _firstName = SanitizeName(value);
        }
    }
}


potrei applicarlo a tutte le proprietà e mettendo la logica del controllo nel metodo chiamato, così sarebbe specifico e residente nel mio oggetto, qualcosa di questo tipo

private object assegnaProprieta(object value)
{
  if (this.bloccato == true)
  {
     throw EccezioneDiQualcheTipo;
  }
  else
  {
    return value:
  }
}


magari usando i generics per non dover castare il valore restituito se riesco ad imparare ad usarli non avendoli mai visti prima
37 messaggi dal 08 agosto 2008
Dopo un pò di studio con i generics direi che si potrebbe fare una cosa del genere:

private T assegnaProprieta<T>(T value)where T: struct
{
  if (this.bloccato == true)
  {
     throw EccezioneDiQualcheTipo;
  }
  else
  {
    return value:
  }
}

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.