Search code examples
c#.netmultithreadingtransactionscope

How can I build class similar to TransactionScope


Basically I'm trying to build something similar to transaction scope but to track changes in objects.

I have an abstract RecordableObject class roughly looking as follows:

public abstract class RecordableObject : INotifyPropertyChanged
{
    protected virtual void RaisePropertyChanged(string prop)
    {
        // remember previous values if recording is on
        var e = PropertyChanged;
        if (e != null)
        {
            e(this, new PropertyChangedEventArgs(prop));
        }
    }

    public void UndoChanges()
    {
    }

    public void StartRecording()
    {
    }

    public void SuspendRecording()
    {
    }

    public void StopRecording()
    {
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

And a recorder whom I want to manage all things:

public class ThreadStaticRecorder : IDisposable, IChangesRecorder
{
    [ThreadStatic]
    private static List<RecordableObject> recordingList;

    public void Record(RecordableObject recordableObject)
    {
        if (recordingList == null)
        {
            recordingList = new List<RecordableObject>();
        }

        recordingList.Add(recordableObject);
    }

    public void Forget(RecordableObject recordableObject)
    {
        if (recordingList == null)
        {
            return;
        }

        recordingList.Remove(recordableObject);
    }

    public void Undo()
    {
    }

    public void Dispose()
    {
        recordingList = null;
    }
}

Now, the point is I don't know how to tie recorder and recordable objects together, and I don't want recordable objects to know anything about recorder.

Ideally, I'd like to be able to use it as follows:

public void TestRecorder(MyClass recorableObj)
{
    recorableObj.Foo = 1;
    using (var recorder = new ThreadStaticRecorder())
    {
         recorableObj.Foo = 2;
         recorder.Undo();
    }

    Console.WriteLine(recorableObj.Foo); // 1
}

Solution

  • The reason TransactionScope works is that the objects affected by it all participate in the transaction system. So in some sense they do "know about" the TransactionScope class.

    What you have there is a cool idea, but I don't think there's anything in the "stock" .NET framework that would allow you to accomplish what you are attempting here without your recordable objects being aware of the recorder in some way.