como-controlar-cambios-en-entidades-en-c-con-trackerdog

Cómo controlar cambios en entidades de C# con TrackerDog

TrackerDog es una librería para .NET que nos permite detectar cambios en entidades de forma sencilla, de forma que sepamos que propiedades se han modificado en el uso de una instancia.

Cuando estamos manejando un ORM como Entity Framework o NHibernate, el propio ORM dispone de control de cambios, de forma que pueden actualizar en la DB únicamente los valores que realmente han cambiado de valor.

Sin embargo, si usamos un micro ORM como Dapper, o incluso sin usar en absoluto una base de datos, con frecuencia encontramos situaciones donde es necesario registrar los cambios de una serie de objetos.

Hacer el control de cambios requiere una gran cantidad de código repetitivo, o usar soluciones ineficientes. Existen varias posibles y librerías posibles para ayudarnos a realizar el control de cambios. TrakerDog una de las más potentes y flexibles, haciendo un esfuerzo en no comprometer la eficiencia.

TrackerDog genera Proxys para nuestras entidades, es decir, objetos que heredan todas las propiedades del original, añadiendo funcionalidades adicionales. De esta forma, estos Proxys son compatibles con casi todo el códigos donde usemos las clases originales.

TrakerDog es compatible con .NET Framework, .NET Core y Xamarin. Es Open Source y el código está disponible en https://github.com/mfidemraizer/trackerdog.

Instalar TrackerDog

TrackerDog está disponible a través de un paquete Nuget, que podemos instalar desde el administrador de paquetes o a través de su consola de comandos haciendo

Install-Package TrackerDog -Version 2.2.4

Usando TrackerDog

Como hemos dicho, TrackerDog genera Proxys por herencia de las nuestras. Por tanto, requiere que todos los métodos y propiedades que queramos registrar sean declarados como virtual. Por ejemplo, supongamos que queremos trackear el siguiente POCO:

public class Employee   
{
  public virtual int Id { get; set; }
  public virtual string Department { get; set; }
  public virtual string Name { get; set; }
  public virtual double Value { get; set; }
  public virtual DateTime Date { get; set; } //(datetime, null)
  public virtual Guid RecordGuid { get; set; } //(uniqueidentifier, null)
}

En primer lugar, tenemos que indicar a TrackerDog las clases que queremos registrar, estableciendo la configuración de la librería.

var config = ObjectChangeTracking.CreateConfiguration();
config.TrackThisType<Employee>();

TrackableObjectFactory = config.CreateTrackableObjectFactory();

A continuación, podemos crear un Proxy de nuestro POCO:

var employee = new Employee();
employee = trackableObjectFactory.CreateFrom(employee);

Alternativamente, si nuestra clase tiene un constructor sin parámetros, podemos crear el Proxy directamente sin tener que pasar una instancia.

var employee = trackableObjectFactory.CreateOf<Employee>();

Con nuestro nuevo Proxy podemos bien acceder a sus propiedades con normalidad, obtener el valor original antes del cambio, o determinar si una propiedad ha cambiado de valor.

var currentName = employee.Name;
var oldName = employee.OldPropertyValue(e => e.Name);
var hasChangeName = employee.PropertyHasChanged(e => e.Name)

También podemos obtener una lista con todas las propiedades modificadas / no modificadas en la instancia.

var changeTracker = employee.GetChangeTracker();
var changedProperties = changeTracker.ChangedProperties;
var unchangedProperties = changeTracker.UnchangedProperties;

Por otro lado, podemos deshacer los cambios realizados en la instancia.

employee.UndoChanges();

Finalmente, si en algún momento queremos obtener un objeto de la clase original, por ejemplo para serializarlo, podemos hacer:

employee = employee.ToUntracked();

TrackerDog tiene muchas más funcionalidades interesantes, como registrar cambios en clases heredades, interfaces, o en colecciones. Tenéis mucha más información en la página del proyecto que, en cualquier caso, conviene visitar.

En conclusión, TrackerDog es una interesante librería para resolver una problemática común, y que puede sernos útil en muchas situaciones evitándonos una gran cantidad de código innecesario.