Il caricamento lento può portare a dati obsoleti, viola IoC?

3

Cercando di essere un programmatore migliore

Ho un'applicazione che tiene traccia dei ruoli e delle autorizzazioni, ho avuto classi per ruolo e autorizzazione che erano solo oggetti valore.

class Role
{
  int RoleID
  string RoleName
}

class Permission
{
  int PermissionID
  string PermissionName
}

Se volessi ottenere le autorizzazioni per un ruolo, lo farei

List<Permission> permissions = PermissionDAL.GetPermissions(RoleID)

Ma per comodità (è un'applicazione desktop) ho dovuto spostare la raccolta dei permessi nella classe Role in modo che potessi fare solo

permissions = roleInstance.GetPermissions();

e la classe Role diventa

class Role
{
  List<Permission> permissions = null;
  int RoleID
  string RoleName

  public List<Permission> Permissions
  {
     get
     {
        if(permissions == null)
           permissions = PermissionDAL.GetPermissions(this.RoleID);

        return permissions;
     }
  }
}

Domanda 1 : la sfida: ecco lo scenario

Role r = getARole();
   //for user to see
display(r.Permissions); 

   //user adding permission to role
RoleDAL.AddPermission(RoleID, PermissionID);

   //display new permissions
display(r.Permissions); 
   //But no, data is not refreshed because of the null check. 
   //Do I need to call a new instance of this Role?

Domanda 2 : penso che questo violi Inversion of Control?

Domanda 3 : come faresti un IoC per List<Role> , impostando le autorizzazioni per ogni ruolo nella raccolta, se dovessi utilizzare IoC.

Grazie

    
posta tunmise fasipe 16.07.2012 - 06:40
fonte

1 risposta

2
  1. Sì, questo comportamento è comune negli oggetti dati con carico lento basati su archivi di dati in rapida evoluzione. Qui imposti una modifica, ma problemi simili possono verificarsi in un sistema multiutente anche quando stai guardando i dati in modalità di sola lettura.

    La soluzione più semplice al tuo problema specifico è aggiungere manualmente l'autorizzazione all'elenco delle autorizzazioni oltre a scriverlo nel database. Tuttavia, ciò non risolve la concorrenza; un altro utente potrebbe aggiungere un permesso dopo averne ricevuto un elenco e non lo saprai mai. Ci sono molte altre soluzioni che risolveranno questo inconveniente; la maggior parte richiede una semplice istruzione SQL per sostituire l'istruzione SQL più grande. Ad esempio, puoi chiedere un conteggio del numero di record e, se questo non corrisponde alla lunghezza della tua lista, ripopolarlo. Puoi anche tenere traccia della "ultima data di modifica" di ciascun elemento nell'elenco e se la data di modifica più recente dei record che utilizzi è più recente della data dell'ultima modifica dei dati che hai, aggiornare i dati. Oppure, puoi semplicemente tenere traccia di quanto tempo fa hai aggiornato l'ultima volta, e se è oltre una certa soglia, i dati sono "obsoleti" e dovrebbero essere aggiornati. Questi richiedono necessariamente un round trip nel database, ma sono query scalari in modo da risparmiare sulla larghezza di banda della rete (e non dovrebbero comportarsi in modo eccessivo contro un DBMS ben strutturato).

  2. No, questo non infrange Inversion of Control, perché questa logica dovrebbe essere inserita nell'accessorio Role.Permissions e quindi è possibile continuare a utilizzare un'istanza risolta come necessario. Anche se non fosse possibile, ci sono modi per iniettare un metodo factory che può essere usato per produrre tanti oggetti Role "scope-factory" (uno per richiesta) di cui potresti avere bisogno.

  3. Dipende dal framework IoC che stai usando (o se non lo stai usando), e da come vuoi che quel framework produca i ruoli. Se si dispone di un metodo factory registrato che accetta un RoleID e genera un oggetto Role, è possibile effettuare tale chiamata tutte le volte che lo si desidera. L'oggetto Role, per sua natura, richiederà quindi qualcosa che può chiamare per ottenere l'elenco delle autorizzazioni. L'iniezione di DAO è un'opzione (e non una cattiva purché il consumo di codice non debba conoscere il DAO), ma preferirei un delegato Func<int, IEnumerable<Permission>> (e un altro Func<IEnumerable<Permission>, bool> che utilizzerai per determinare se è necessario aggiornare i dati) che è possibile inserire nel ruolo e che il ruolo può essere utilizzato senza dover sapere da dove proviene; quindi, se necessario, puoi praticamente strappare il tuo livello di accesso ai dati e iniziare completamente da zero, senza che nessun altro oggetto sappia la differenza.

risposta data 16.07.2012 - 16:55
fonte