Un sistema di log automatico con gli Interceptor di NHibernate

di Marco De Sanctis, in ASP.NET 2.0, NHibernate, UserScript,

Può spesso capitare di voler ricevere una notifica in corrispondenza di un'operazione effettuata da NHibernate su database, ad esempio per realizzare un piccolo sistema di logging che tenga traccia delle azioni degli utenti.

Una valida soluzione consiste nel creare un Interceptor, i cui metodi vengono automaticamente invocati dalla Session prima dell'esecuzione di ogni query. Per farlo, è sufficiente implementare l'interfaccia Iinterceptor o, come migliore alternativa, ereditare da EmptyInterceptor (che non ha alcuna logica al suo interno) ed effettuare l'override dei soli metodi d'interesse:

public class LoggerInterceptor: EmptyInterceptor
{
  private string username;

  public LoggerInterceptor(string username)
  {
    this.username = username;
  }

  public override void OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types)
  {
    base.OnDelete(entity, id, state, propertyNames, types);
    if (entity is IAuditable)
    {
      logEvent("Update", entity, id);
    }
  }

  // analogamente per 
  // OnFlushDirty -> UPDATE
  // OnSave -> INSERT
}

Il metodo LogEvent non fa altro che creare una nuova Session e memorizzare le informazioni relative al log:

private void logEvent(string eventType, object entity, object entityId)
{
  using (ISession logSession = SessionHelper.GetSession())
  {
    LogEntry entry = new LogEntry();
    entry.Username = username;
    entry.DataOra = DateTime.Now;
    entry.EntityId = entityId.ToString();
    entry.TipoEntity = entity.GetType().Name;
    entry.TipoOperazione = eventType;
    logSession.Save(entry);
    logSession.Flush();
  }
}

L'interfaccia IAuditable è un semplice marker: non possiede infatti alcun membro e serve solo ad indicare quali entità devono essere soggette a Log; nel nostro caso, ad esempio, viene tenuto traccia di quanto accade sulle fatture, ma si trascurano le singole operazioni sui dettagli.
Per utilizzare l'Interceptor appena creato, è sufficiente fornirlo come parametro al metodo per la creazione della Session:

public static ISession GetSession(string username)
{
  LoggerInterceptor interceptor = new LoggerInterceptor(username);
  return sessionFactory.OpenSession(interceptor);
}

A questo punto uno snippet simile al seguente, eseguito in un'applicazione ASP.NET, produce anche una nuova riga nella tabella di log con gli estremi dell'autore e dell'oggetto modificato.

using (ISession session = SessionHelper.GetSession(HttpContext.Current.User.Identity.Name))
{
  session.SaveOrUpdate(fattura);
  session.Flush();
}

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi