2015-08-11 3 views
2

Я занимаюсь службой REST (используя удивительный ServiceStack, хотя это не относится к вопросу), и теперь мне нужно внести изменения в журнал, которые произойдут по запросу PUT.Лучший подход к изменениям журнала при PUT

В настоящее время мой подход обновление как:

public object Put(PostActivityInformation request) 
{ 
    var session = this.SessionAs<MyCustomApiAuthSession>(); 

    var activity = _activitiesRepository.GetActivityById(_companyRepository, session.CurrentCompany.Guid, request.Id); 

    if (_activitiesRepository.IsActivityDuplicated(session.CurrentCompany.Id, request.SmsCode, request.Name, request.Id)) 
     return HttpError.Conflict("Found a duplicated activity"); 

    // update what is passed 
    activity.Category = request.Category ?? activity.Category; 
    activity.Description = request.Description ?? activity.Description; 
    activity.ExtraTextDescription = request.ExtraTextDescription ?? activity.ExtraTextDescription; 
    activity.Name = request.Name ?? activity.Name; 
    activity.Points = request.Points ?? activity.Points; 
    activity.SaveExtraText = request.SaveExtraText ?? activity.SaveExtraText; 
    activity.SmsCode = request.SmsCode ?? activity.SmsCode; 

    activity.IsActive = request.Active ?? activity.IsActive; 
    activity.IsArchived = request.Archived ?? activity.IsArchived; 

    // update stamp 
    activity.UpdatedTime = DateTime.UtcNow; 
    activity.UpdatedUser = session.CurrentUser.Id; 

    // save 
    _activitiesRepository.SaveOrUpdate(activity); 

    // log 
    session.AddLog("Activity updated: {0}".Fmt(activity.Name), LogArea.Activities, activity.Id); 

    return activity.ToActivityResponse(); 
} 

Но я хотел бы быть более описательный характер, а также сохранить изменения, что-то вроде замены

activity.Category = request.Category ?? activity.Category; 
activity.Description = request.Description ?? activity.Description; 

по

var log = new StringBuilder(); 
if (request.Category != null) 
{ 
    log.AppendFormat("Category changed from '{0}' to '{1}'", activity.Category, request.Category); 
    activity.Category = request.Category; 
} 
if (request.Description != null) 
{ 
    log.AppendFormat("Description changed from '{0}' to '{1}'", activity.Description, request.Description); 
    activity.Description = request.Description; 
} 

а затем сохраните переменную log в моей таблице аудита ...

Какой должен быть наилучший подход, поскольку у меня есть несколько обновлений API, а не только «действия»?

Я думал о метода расширения, но это будет использовать трапезы и Уилл медленнее вещи немного ...

ли кто-нибудь из вас уже прошел, хотя этот вопрос, что вы делали?

ответ

2

Один из подходов в формат журнала, как вы измените настройки с помощью пары вспомогательных методов:

private static void T? Update(T? newVal, T? oldVal, string name, StringBuilder log) where T : struct { 
    if (!Equals(newVal, oldVal)) { 
     log.AppendFormat("{0} changed from '{1}' to '{2}'", name, oldVal, newVal); 
    } 
    return newVal ?? oldVal; 
} 
private static void T Update(T newVal, T oldVal, string name, StringBuilder log) where T : class { 
    if (!Equals(newVal, oldVal)) { 
     log.AppendFormat("{0} changed from '{1}' to '{2}'", name, oldVal, newVal); 
    } 
    return newVal ?? oldVal; 
} 

Теперь вы можете объединить свой код следующим образом:

activity.Category = Update(request.Category, activity.Category, nameof(activity.Category), log); 
activity.Description = Update(request.Description, activity.Description, nameof(activity.Description), log); 
activity.ExtraTextDescription = Update(request.ExtraTextDescription, activity.ExtraTextDescription, nameof(activity.ExtraTextDescription), log); 
... 

Примечание: I предположим, что на данный момент у вас нет большой гибкости при изменении архитектуры, но хороший альтернативный подход к проведению аудита - позволить аудиту быть вашим основным источником информации о том, что изменилось. Конечно, это преобразовывает журнал аудита из списка форматированных строк в полномасштабный реестр объектов. См. Event Sourcing Pattern для более подробной информации.

+0

Я нахожусь в процессе даже проектирования базы данных, поэтому мне просто нужно немного больше узнать о шаблоне ES, спасибо! – balexandre

+0

, но подождите ... У меня не будет «классического» реляционного хранилища данных ... и потребуется гораздо больше времени для выполнения такого процесса: (сейчас я буду использовать путь EXtMethods, но буду смотреть в глубину в шаблон ES ! для всех там, как и я, не зная точно, как делать ES, проверьте [это видео] (https://www.youtube.com/watch?v=z5FPkCgcH4M), чтобы начать. – balexandre

0

Я бы применил нечто вроде INotifyPropertyChanged в вашем классе Activity, где в данных события у вас будет имя свойства, старое значение и новое значение.

Смежные вопросы