Pergunta

Atualmente estou desenvolvendo um sistema de recursos ASP.NET Humano. Eu estou usando uma arquitetura em camadas com Fábrica de Software Web Client, que é baseado no padrão MVP. ORM é NHibernate. E eu preciso implementar um módulo de log de auditoria. Eu li muito sobre diferentes abordagens. A maioria deles descrevem como rastrear data, timastamp e identidade da pessoa que fez essa mudança, mas ninguém poderia me dizer sobre isso: como controlar as alterações de qualquer propriedade em minha camada de domínio? Eu não preciso de qualquer recurso de rollback, eu só precisa de Log com:. Quem, quando e qual propriedade do que objeto foi mudado, valor antigo eo novo valor dessa propriedade

Eu não posso decidir onde colocar o manipulador destas alterações. Fowler apontou um log de auditoria no método setter de propriedades, mas eu ainda quero manter minhas classes de domínio POCO`s simples. Talvez haja alguma outra abordagem?

Foi útil?

Solução

Eu tive que fazer isso há alguns anos atrás para um sistema de RH também. Eu realizei que ter todos os meus 'campos' implementar um modelo (genérico):

Aqui está um exemplo do modelo que eu fiz aparadas para baixo:

class DataField<T>
{
    public T Current { get; set; }
    public T Original { get; set; }
    // stores the field name as a nice textual readable representation.
    // would default to property name if not defined.
    public string FieldName { get; set; }
    public bool Modified
    {
        get { return !(Current.Equals(Original));
    }

    public DataField(T value)
    {
        Original = Current = value;
    }

    public DataField(T value, T fieldName)
    {
        Original = Current = value;
        FieldName = fieldName;
    }
}

A parte interessante sobre isso que fez auditting fácil era que cada objeto poderia produzir é próprio log de auditoria. Eu poderia tomar qualquer objeto que poderia ter x número destes 'campos' e chamar o GetAudit nele e ele me retornar um objeto de auditoria com todas as mudanças para a classe que mostram o nome do campo, val velho, novo val etc .. Cada 'DataField' poderia implementar um método para retornar um objeto de auditoria. Para strings, duplos, ints etc foi muito bem cozido em mas se você usou objetos personalizados, você pode escrever a implementação de auditoria para eles, que apenas teve que retornar um objeto de auditoria.

Assim, em uma forma típica no final eu teria todos os dados armazenados em um objeto que tinha todos esses tipos de campos. Eu, então, fazer uma atualização e chamar o método GetAudit que também seria escrito para uma tabela de auditoria também.

Eu poderia facilmente dizer se alguma coisa havia mudado na forma, mesmo que eles tiveram que passar por várias páginas, etc.

Desfazer eram realmente fácil em um campo a campo, seção por seção ou todo o nível do objeto também.

Little nebuloso sobre os detalhes exatos que eu não toquei o código em um longo tempo, mas que foi a essência dele. Espero que ajude.

Outras dicas

Talvez você pode implementar o padrão de observador, no entanto, uma vez que implementa .net este padrão implicitamente (com eventos) Eu acho que o valor não será muito acrescentou.

Talvez você possa salvar as objetcs "orginal" e compará-los com os objetos modificados quando o tempo é direito (talvez usando a reflexão) e descobrir o que propriedades foram alterados e que seu novo valor é. No entanto, nota que você não pode fazer deepcopies de objetos no .net (exceto se você pode serializar os objetos), de modo a manter isso em mente para esta solução

Ou você precisa manter os dados originais em torno de seu objeto ou retirá-lo do banco de dados para o registo antes da atualização.

Eu vi isso implementado na camada de dados, seja em procedimentos ou gatilhos armazenados, mas nunca na camada de domínio.

Edit: Um exemplo 2 parte de usar gatilhos de banco de dados para registrar a história é encontrado aqui: http://www.4guysfromrolla.com/webtech/041807-1.shtml Não parece muita boa discussão sobre as vantagens / desvantagens desta técnica. Espero que ajuda.

Você verificou o href="http://msdn.microsoft.com/en-us/library/cc309506.aspx" rel="nofollow noreferrer"> Logging da Microsoft Enterprise Library?

scroll top