Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IsDirty Flag Pattern

Tags:

c#

.net

I have a base class for a BLL that includes the following function:

    public bool IsDirty { get; protected set; }

    internal void SetField<TParam>(ref TParam field, TParam value)
    {
        if (EqualityComparer<TParam>.Default.Equals(field, value) == false)
        {
            field = value;
            IsDirty = true;
        }
    }

In the classes that inherit the base class I use this as a wrapper around the SET object, such as:

    public string UserName
    {
        get { return _userName; }
        set { SetField(ref _userName, value); }
    }

I use the IsDirty property to test to see if I need to issue an Update. If at least one of the properties changes then save to database. This works for most types but Collections and Lists can change without using set. I wrote a wrapper for the Collection to have an IsDirty flag on the List which could be tested for change:

    public class CollectionChangeTracked<T> : Collection<T>
    {
        public bool IsDirty {get; set;}

        public CollectionChangeTracked()
        {
            IsDirty = false;
        }

        protected override void InsertItem(int index, T newItem)
        {
            base.InsertItem(index, newItem);
            IsDirty = true; 
        }

        protected override void SetItem(int index, T newItem)
        {
            base.SetItem(index, newItem);
            IsDirty = true;
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
            IsDirty = true;
        }

        protected override void ClearItems()
        {
            base.ClearItems();
            IsDirty = true;
        }
    }
}

The problem is that I now have to test both the Classe's IsDirty property and any CollectionChangeTracked.IsDirty flags for updates. I could create method that performs the test in one spot such as:

    public CollectionChangeTracked<ApplicationRole> RolesList
    {
        get { return _rolesList; }
        set { SetField(ref _rolesList, value); }
    }

    public override bool IsDirty
    {
        get { return ResolveIsDirty(); }
        protected set { _isDirty = value; }

    private bool ResolveIsDirty()
    { 
        bool returnValue;

        if (_isDirty || RolesList.IsDirty)
            returnValue = true;
        else
            returnValue = false;

        return returnValue;
    }

But it seems like I should be able to come up with a cleaner solution that would allow a Class that contains the Collection to subscribe to a change of IsDirty of the CollectionChangeTracked object and update the IsDirty based on that change. Is this the better approach and how would I implement?

like image 585
Josh Avatar asked Oct 12 '12 18:10

Josh


People also ask

What is a Dirtyflag?

Dirty flagging is playing from a losing or drawing position and then winning because your opponent's time runs out - usually by throwing in extraneous or sacrificial checks to force your opponent's time to run low.

What does it mean if a page is dirty?

A 'dirty page' refers to a page that has been updated in memory only, the changes to a dirty page are not yet stored on disk. Ben Schmeckpeper.


1 Answers

you can use an ObservableCollection<T> register to the CollectionChanged event and mark the IsDirty flag when the event is raised.

...

ObservableCollection<int> myCollection = new ObservableCollection<int>();
myCollection.CollectionChanged += OnCollectionChanged;

...

public void OnCollectionChanged( Object sender, NotifyCollectionChangedEventArgs e )
{
   IsDirty = true;
}
like image 86
Alex Gelman Avatar answered Oct 31 '22 06:10

Alex Gelman