Tworzymy więc sobie interfejs który będzie miał zadeklarowane właściwości opisujące audyt np.
public interface IAuditObject
{
DateTime CreatedDateTime { get; set; }
int CreatedUserId { get; set; }
DateTime ModifyDateTime { get; set; }
int ModifyUserId { get; set; }
}
Teraz wyposażamy klasę naszej encji w ten interfejs. Oczywiście trzeba uzupełnić pliki mapowania o te informacje.
Do przeprowadzenia audytu wykorzystamy dwa zdarzenia które są dostępne: IPreInsertEventListener oraz IPreUpdateEventListener. Te zdarzenia są wywoływane przed dodaniem/zapisem encji. Omówimy teraz sposób implementacji IPreInsertEventListener bo te drugie zdarzenie będzie praktycznie wyglądało bardzo podobnie a różnica będzie w postaci mniejszej ilości pól do zmienienia. A więc jej implementacja mogła by wyglądać następująco:
public bool OnPreInsert(PreInsertEvent @event)
{
if (UpdateAuditInformation(@event.Entity))
{
var entity = @event.Entity as IAuditObject;
Set(@event.Persister, @event.State, "CreatedDateTime", entity.CreatedDateTime);
Set(@event.Persister, @event.State, "ModifyDateTime", entity.ModifyDateTime);
Set(@event.Persister, @event.State, "CreatedUserId", entity.CreatedUserId);
Set(@event.Persister, @event.State, "ModifyUserId", entity.ModifyUserId);
}
return false;
}
W klasie PreInsertEvent są m.in następujące rzeczy:
- instancja naszej encji na której dokonujemy wpisu audytu @event.Entity
- instancja klasy mapującej i zapisującej naszą encje @event.Persister
- tablica wartości które zostaną dodane/zapisane do bazy @event.State
.
Teraz musimy ustawić informacje na temat audytu w naszej encji oraz tablicy stanów. Aby rozpoznać co gdzie leży w tej tablicy możemy skorzystać z obiektu Persister i jego właściwości PropertyNames.
Przykładowa implementacja metody pomocniczej to:
private static void Set(IEntityPersister persister, object[] state, string propertyName, object value)
{
var index = Array.IndexOf(persister.PropertyNames, propertyName);
if (index != -1)
{
state[index] = value;
}
}
Metoda UpdateAuditInformation ustawia nam na encji odpowiednie wartości czasu utworzenia/modyfikacji oraz np ID użytkownika który
wykonał operacje.
Zostaje nam tylko teraz powiadomienie NHibernate o naszej obsłudze tych zdarzeń a możemy to zrobić np:
...
var configuration = new Configuration();
configuration.Configure();
var auditor = new DatabaseAuditor();
configuration.SetListener(ListenerType.PreInsert, auditor);
configuration.SetListener(ListenerType.PreUpdate, auditor);
_sessionFactory = configuration.BuildSessionFactory();
...
0 komentarze:
Prześlij komentarz