I have built a large model/system that uses INotifyPropertyChanged and IChangeTracking to track changes to any entity in the system:
public abstract class DependancyObject : INotifyPropertyChanged, IChangeTracking
{
protected DependancyObject()
{
this.PropertyChanged += new PropertyChangedEventHandler(OnNotifiedOfPropertyChanged);
}
private void OnNotifiedOfPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e != null && !String.Equals(e.PropertyName, "IsChanged", StringComparison.Ordinal))
{
this.IsChanged = true;
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
OnPropertyChangedExplicit(propertyName);
}
protected void OnPropertyChanged<TProperty>(Expression<Func<TProperty>> projection)
{
var memberExpression = (MemberExpression)projection.Body;
OnPropertyChangedExplicit(memberExpression.Member.Name);
}
void OnPropertyChangedExplicit(string propertyName)
{
//thread safe
PropertyChangedEventHandler handler;
lock (this)
{
handler = PropertyChanged;
}
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region IChangeTracking
public void AcceptChanges()
{
this.IsChanged = false;
}
public bool IsChanged
{
get
{
lock (_notifyingObjectIsChangedSyncRoot)
{
return _notifyingObjectIsChanged;
}
}
protected set
{
lock (_notifyingObjectIsChangedSyncRoot)
{
if (!Boolean.Equals(_notifyingObjectIsChanged, value))
{
_notifyingObjectIsChanged = value;
this.OnPropertyChanged("IsChanged");
}
}
}
}
private bool _notifyingObjectIsChanged;
private readonly object _notifyingObjectIsChangedSyncRoot = new Object();
#endregion
}
This works very well. I have a lot of code that loops through object trees resetting the entity by calling AcceptChanges(). I was wandering whether someone has used reflection before to inspect each property of a type, and if it implements IChangeTracking or IEnumerable to call AcceptChanges recursively so it will navigate an instances entire tree.
private void BulkAcceptChanges(IEnumerable<IChangeTracking> items)
{
foreach (var item in items)
{
item.AcceptChanges();
//then inspect the item's properties for anything that implements IEnumerable<IChangeTracking>
//and call BulkAcceptChanges on that
}
}
Aucun commentaire:
Enregistrer un commentaire