Assigning Recorders Manually

By default, all recordable objects are attached to the global Recorder exposed on the RecordingServices.DefaultRecorder property. There is nothing you have to do to make this happen. There may be circumstances where you want to create and assign your own recorder to the undo/redo process. There are two different ways that you can accomplish this.

This topic contains the following sections:

Overriding the default RecorderProvider

By default, the RecordableAttribute aspect attaches an object to a Recorder as soon as its constructor exits. To determine which Recorder should be used, the aspect uses the RecordingServices.RecorderProvider service. By default, this service always serves the global instance that is also exposed on the RecordingServices.DefaultRecorder property.

You can override this automatic assignment to inject your own RecorderProvider to into the process.

To use a custom RecorderProvider:

  1. Create a class inherited from the RecorderProvider class.

    C#
    public class MyProvider : RecorderProvider
    {                
    }
  2. Implement the chaining constructor. The RecorderProvider that you inherited from requires a RecorderProvider as a constructor parameter. This constructor parameter facilitates the chain of responsibility for providers that can be run when a Recorder is requested. To keep the chain of responsibility intact your custom RecorderProvider will need to accept a RecorderProvider in it's constructor and pass that to the base constructor.

    C#
    public class MyProvider : RecorderProvider
    {
      public MyProvider(RecorderProvider next) : base (next)
      {
      }
    }
  3. Override the GetRecorderCore(Object) method.

    C#
    public class MyProvider : RecorderProvider
    {                
      public MyProvider(RecorderProvider next) : base(next)
      {
      }
    
      public Recorder GetRecorderImpl(object obj)
      {
        //where you will write code to create a new Recorder instance
        throw new NotImplementedException();
      }
    }
  4. Insert an instance of your custom RecorderProvider class into the chain of responsibility by assigning it to the RecordingServices.RecorderProvider.

    C#
    RecordingServices.RecorderProvider = new MyProvider(RecordingServices.RecorderProvider);
Note Note

RecorderProvider is a chain of responsibility. As such, if a GetRecorderCore(Object) method returns null then the chain will move on to the next RecorderProvider and attempt to get a Recorder to use.

By overriding the default RecorderProvider you are able to assign a custom Recorder across the entire application.

Attaching a recorder manually

The second way that you can add a Recorder to objects is to manually assign them when, and where, they are needed.

To manually assign a Recorder to an object:

  1. Set the RecordableAttribute.AutoRecord property to false for that class.

    C#
    [Recordable(AutoRecord = false)]
    public class Invoice
    {
    }
    Note Note

    By disabling AutoRecord you are telling the RecordingServices that this object should not be included in recordings unless the recording is explicitly declared in your code.

  2. Create a new instance of a Recorder and attach the object to it using the Attach(Object) method.

    C#
     var invoice = new Invoice();
    
    var recorder = new Recorder();
    recorder.Attach(invoice);

    You can then use the Detach(Object) method to remove the Recorder from the object in question.

Note Note

An object must always have the same Recorder as its parent has unless the parent has no Recorder assigned. Because of this, whenever a Recorder is assigned to an object, all of the child objects will have that same Recorder assigned to them. However, if you detatch a child object from it's parent the child object's assigned Recorder will not be detached. For more information about parent-child relationships, see Parent/Child Relationships.