Explicit Property Memento

Introduction

Some weeks ago I’ve introduced the Property Memento pattern as solution for temporarily saving the state of an entity’s property on creation of the Property Memento and restoring this initial state when the Property Memento disposes. I’ve shown that the using(){} syntax separates between the Property Memento initialization and the core logic which should be run inside the Memento with temporarily changed property values.

While I like the pattern and its usage, I see that the using syntax can be disturbing for developers who don’t know the internal implementation of the Property Memento. The implementation mixes using as common syntax with other semantics, which violates the uniformity principle of computer science.

A colleague suggested an implementation of the pattern, which makes the three steps in a Property Memento’s lifetime explicit:

  1. Memorize the current properties values.
  2. Invoke some actions.
  3. Restore the memorized values.

I’ve adopted his implementation to fit my needs of memorizing properties even for more than one entity.

Explicit Property Memento implementation

The implementation of the Explicit Property Memento projects the 3 steps of a Property Memento by the methods Memorize(), Invoke() and RestoreValues(). Thus the intention is revealed, which yields to a better understanding of the whole process. Instead of memorizing one property of just a single entity on the creation of the Property Memento, the ExplicitPropertyMemento has the ability to store several property values of more than one entity. This makes the implementation a bit heavier, but the usage very smart. First here’s the implementation part:

public class ExplicitPropertyMemento
{
    class MemorizedProperty
    {
        public string Name { get; set; }
        public object Value { get; set; }
    }

    private readonly IDictionary<object, List<MemorizedProperty>> _memorizedProperties
        = new Dictionary<object, List<MemorizedProperty>>();

    public static ExplicitPropertyMemento Create
    {
        get { return new ExplicitPropertyMemento(); }
    }

    public ExplicitPropertyMemento Memorize(
        object classInstance, params Expression<Func<object>>[] propertySelectors)
    {
        if(propertySelectors == null)
            return this;

        var properties = new List<MemorizedProperty>();
        foreach(var propertySelector in propertySelectors)
        {
            string propertyName = GetPropertyName(propertySelector);
            properties.Add(new MemorizedProperty
                {
                    Name = propertyName,
                    Value = GetPropertyValue(classInstance, propertyName)
                });
        }

        if(_memorizedProperties.ContainsKey(classInstance))
            _memorizedProperties[classInstance].AddRange(properties);
        else
            _memorizedProperties.Add(classInstance, properties);

        return this;
    }

    public ExplicitPropertyMemento Memorize<TProperty>(object classInstance,
        Expression<Func<object>> propertySelector, TProperty tempValue)
    {
        Memorize(classInstance, propertySelector);

        string propertyName = GetPropertyName(propertySelector);
        SetPropertyValue(classInstance, propertyName, tempValue);

        return this;
    }

    public ExplicitPropertyMemento Invoke(Action action)
    {
        try
        {
            action.Invoke();
        }
        catch
        {
            RestoreValues();
            throw;
        }

        return this;
    }

    public void RestoreValues()
    {
        foreach(var memorizedEntity in _memorizedProperties)
        {
            object classInstance = memorizedEntity.Key;
            foreach(var property in memorizedEntity.Value)
                SetPropertyValue(classInstance, property.Name, property.Value);
        }
    }

    private string GetPropertyName(Expression<Func<object>> propertySelector)
    {
        var body = propertySelector.Body;
        if (body.NodeType == ExpressionType.Convert)
            body = ((UnaryExpression)body).Operand;
        return ((MemberExpression)body).Member.Name;
    }

    private object GetPropertyValue(object classInstance, string propertyName)
    {
        return classInstance
            .GetType()
            .GetProperty(propertyName)
            .GetValue(classInstance, null);
    }

    private void SetPropertyValue(object classInstance, string propertyName, object value)
    {
        classInstance
            .GetType()
            .GetProperty(propertyName)
            .SetValue(classInstance, value, null);
    }
}

Usage example

The usage is explicitly projecting the Property Memento process by the methods Memorize(), Invoke() and RestoreValues() and it’s straightforward. In case of the introductory example it’s shown next:

private void SomeMethod(...)
{
    int oldValSumHeight = _valSum.Height;
    int newValSumHeight = 0;

    var newAnchor = AnchorStyles.Top | AnchorStyles.Left;
    ExplicitPropertyMemento.Create
        .Memorize(_valSum, () => _valSum.AutoSize, true)
        .Memorize(_valSum, () => _valSum.Anchor, newAnchor)
        .Memorize(_detailContent, () => _detailContent.Anchor, newAnchor)
        .Invoke(() =>
            {
                _valSum.SetValidationMessages(validationMessages);

                newValSumHeight = _valSum.Height;
                Height = Height - oldValSumHeight + newValSumHeight;
            })
        .RestoreValues();

    _valSum.Height = newValSumHeight;
}

Alternatively the ExplicitPropertyMemento implementation allows specifying more than one property as argument for the Memorize() method, if you don’t want to set the new property value directly by this method. Thus you could use some code like this:

private void SomeMethod(...)
{
    int oldValSumHeight = _valSum.Height;
    int newValSumHeight = 0;

    ExplicitPropertyMemento.Create
        .Memorize(_valSum, () => _valSum.AutoSize, () => _valSum.Anchor)
        .Memorize(_detailContent, () => _detailContent.Anchor)
        .Invoke(() =>
            {
                _valSum.AutoSize = true;
                _valSum.Anchor = AnchorStyles.Top | AnchorStyles.Left;
                _detailContent.Anchor = AnchorStyles.Top | AnchorStyles.Left;

                _valSum.SetValidationMessages(validationMessages);

                newValSumHeight = _valSum.Height;
                Height = Height - oldValSumHeight + newValSumHeight;
            })
        .RestoreValues();

    _valSum.Height = newValSumHeight;
}

Conclusion

Instead of the using syntax this article has shown an Explicit Property Memento implementation, which makes the whole Property Memento process explicit by defining methods for each step of the process. I still like the using syntax because it’s very dense, but in terms of intention revealing I also like the ExplicitPropertyMemento. What’s your opinion? At least feel free to choose the implementation you prefer 🙂

kick it on DotNetKicks.com

Follow-up: Property Memento pattern

In a previous blog post I introduced the Property Memento pattern as way to temporarily save the value of an entity’s properties and restoring the initial values when the memento disposes.

While I like the pattern itself I think the syntax can be done better. Here comes an implementation that uses just one type parameter for the property type and misses the reflection helper. The static class PropertyMemento helps to generate PropertyMemento<T> instances without specifying the type parameter (it’s inferred by the compiler):

public class PropertyMemento<TProperty> : IDisposable
{
    private readonly TProperty _originalPropertyValue;
    private readonly object _classInstance;
    private readonly string _propertyName;

    public PropertyMemento(object classInstance,
        Expression<Func<TProperty>> propertySelector)
    {
        _classInstance = classInstance;
        _propertyName = ((MemberExpression)propertySelector.Body).Member.Name;
        _originalPropertyValue = GetPropertyValue();
    }

    public PropertyMemento(object classInstance,
        Expression<Func<TProperty>> propertySelector, TProperty tempValue)
        : this(classInstance, propertySelector)
    {
        SetPropertyValue(tempValue);
    }

    public void Dispose()
    {
        SetPropertyValue(_originalPropertyValue);
    }

    private TProperty GetPropertyValue()
    {
        return (TProperty)_classInstance
            .GetType()
            .GetProperty(_propertyName)
            .GetValue(_classInstance, null);
    }

    private void SetPropertyValue(TProperty value)
    {
        _classInstance
            .GetType()
            .GetProperty(_propertyName)
            .SetValue(_classInstance, value, null);
    }
}

public static class Memento
{
    public static PropertyMemento<TProperty> From<TProperty>(object classInstance,
        Expression<Func<TProperty>> propertySelector)
    {
        return new PropertyMemento<TProperty>(classInstance, propertySelector);
    }

    public static PropertyMemento<TProperty> From<TProperty>(object classInstance,
        Expression<Func<TProperty>> propertySelector, TProperty tempValue)
    {
        return new PropertyMemento<TProperty>(classInstance, propertySelector, tempValue);
    }
}

And now its usage in the same scenario shown in the original blog post:

private void SomeMethod(...)
{
    int oldValSumHeight = _valSum.Height;
    int newValSumHeight = 0;

    AnchorStyles newAnchor = AnchorStyles.Top | AnchorStyles.Left;
    using (PropertyMemento.From(_valSum, () => _valSum.AutoSize, true))
    using (PropertyMemento.From(_valSum, () => _valSum.Anchor, newAnchor))
    using (PropertyMemento.From(_detailContent, () => _detailContent.Anchor, newAnchor))
    {
        _valSum.SetValidationMessages(validationMessages);

        newValSumHeight = _valSum.Height;
        Height = Height - oldValSumHeight + newValSumHeight;
    }

    _valSum.Height = newValSumHeight;
}

As said before: just a little improvement to the original code which slightly improves the implementation and usage of the pattern…

Simple message-based Event Aggregator

This blog post is more about implementation than in-depth description or background information. It’s covering an implementation of a simple Event Aggregator that I’ve developed and used in a non-trivial Silverlight project and which I found quite useful. A word of warning: It’s not fully fledged and not suited for all scenarios… and it’s not intended to be.

(Little) background

Event broker linkage, Copyright: Matthias JauernigThe first time I’ve seen an implementation of the event aggregator pattern was in the Prism framework. I like the idea behind this pattern. It’s decoupling event publishers and subscribers. It’s representing a kind of Hub. Each time a publisher publishs an event it gets into the hub and then it’s redirected to the subscribers. The publishers/subscribers don’t have to know each other, they just have to know the concrete event aggregator which is a mediator and mediates between both parties. Thus the event aggregator is realizing a useful indirection mechanism.

The event aggregator can be used in many scenarios and situations. I’ve mainly used it in UI-related scenarios, but it’s not limited to that. In the UI situation it helped me out e.g. at view synchronization and indirect communication: between multiple user controls/views, views and view models (both directions) or views and controllers. They don’t have to know each other and thus can be loosely coupled.

While I came across with the Prism event aggregator at first, after some investigation I didn’t like the implementation very much in view of the usage from a client’s perspective. You first have to get an event from the event aggregator and then you can subscribe to this event or publish the event with some event arguments. This is kind of duplicated work. When I know the type of the event arguments why do I have to know the event anymore (under the assumption that there’s a 1:1 relationship between both)? Others came across with this issue as well. A better approach in my opinion is a solely message-based event aggregator. A system that doesn’t distinguish between events and event arguments, but is based on messages people can subscribe to and publish.

Implementation

Let’s come to the bits’n’bytes of my implementatoin. My message-based event aggregator should be able to handle messages of type IMessage. This is just an empty interface for type-correctness in the other components. Additionally it makes the message type explicit which I like because a message should be a very specific type of your application domain:

public interface IMessage { }

Another important component is the ISubscription<TMessage> interface and its default implementation Subscription<TMessage>. A subscription is something the event aggregator stores internally when an action should be subscribed to a message. This subscription process results in an ISubscription<TMessage> object, which is returned to the caller. The caller will be able to unsubscribe from the event aggregator with this subscription object – there’s no need to reference the subscribed action, which is handy e.g. in situations where you want to use anonymous methods (via delegates or lambdas). Furthermore when the subscription disposes it’s unsubscribed from the event aggregator, which I found quite useful:

public interface ISubscription<TMessage> : IDisposable
    where TMessage : IMessage
{
    Action<TMessage> Action { get; }
    IEventAggregator EventAggregator { get; }
}

public class Subscription<TMessage> : ISubscription<TMessage>
    where TMessage : IMessage
{
    public Action<TMessage> Action { get; private set; }
    public IEventAggregator EventAggregator { get; private set; }

    public Subscription(IEventAggregator eventAggregator, Action<TMessage> action)
    {
        if(eventAggregator == null) throw new ArgumentNullException("eventAggregator");
        if(action == null) throw new ArgumentNullException("action");

        EventAggregator = eventAggregator;
        Action = action;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if(disposing)
            EventAggregator.UnSubscribe(this);
    }
}

Note the reference to EventAggregator in the interface and its use in the implementation. This is necessary due to the disposing functionality. Of course if you don’t want this behavior in your scenario you can adapt the implementation.

At the end the IEventAggregator interface and its default implementation EventAggregator handle the whole message publish/subscribe mechanism. Clients can Subscribe() to specific types of messages with custom actions that are stored in an ISubscription<TMessage> object. Those clients can UnSubscribe() if they’re owning the ISubscription<TMessage> object. Other clients can Publish() concrete messages, which gets the subscribers of the message notified:

public interface IEventAggregator
{
    void Publish<TMessage>(TMessage message)
        where TMessage : IMessage;

    ISubscription<TMessage> Subscribe<TMessage>(Action<TMessage> action)
        where TMessage : IMessage;

    void UnSubscribe<TMessage>(ISubscription<TMessage> subscription)
        where TMessage : IMessage;

    void ClearAllSubscriptions();
    void ClearAllSubscriptions(Type[] exceptMessages);
}

public class EventAggregator : IEventAggregator
{
    private readonly IDictionary<Type, IList> _subscriptions = new Dictionary<Type, IList>();

    public void Publish<TMessage>(TMessage message)
        where TMessage : IMessage
    {
        if(message == null) throw new ArgumentNullException("message");

        Type messageType = typeof(TMessage);
        if(_subscriptions.ContainsKey(messageType))
        {
            var subscriptionList = new List<ISubscription<TMessage>>(
                _subscriptions[messageType].Cast<ISubscription<TMessage>>());
            foreach(var subscription in subscriptionList)
                subscription.Action(message);
        }
    }

    public ISubscription<TMessage> Subscribe<TMessage>(Action<TMessage> action)
        where TMessage : IMessage
    {
        Type messageType = typeof(TMessage);
        var subscription = new Subscription<TMessage>(this, action);

        if(_subscriptions.ContainsKey(messageType))
            _subscriptions[messageType].Add(subscription);
        else
            _subscriptions.Add(messageType, new List<ISubscription<TMessage>>{subscription});

        return subscription;
    }

    public void UnSubscribe<TMessage>(ISubscription<TMessage> subscription)
        where TMessage : IMessage
    {
        Type messageType = typeof(TMessage);
        if (_subscriptions.ContainsKey(messageType))
            _subscriptions[messageType].Remove(subscription);
    }

    public void ClearAllSubscriptions()
    {
        ClearAllSubscriptions(null);
    }

    public void ClearAllSubscriptions(Type[] exceptMessages)
    {
        foreach (var messageSubscriptions in new Dictionary<Type, IList>(_subscriptions))
        {
            bool canDelete = true;
            if (exceptMessages != null)
                canDelete = !exceptMessages.Contains(messageSubscriptions.Key);

            if (canDelete)
                _subscriptions.Remove(messageSubscriptions);
        }
    }
}

Usage

The usage of this event aggregator implementation is simple and straight forward. Clients can subscribe to messages they’re interested in:

// Option 1: Explicit action subscription
Action<MyMessage> someAction = message => { /*...*/ };
var subscription1 = eventAggregator.Subscribe(someAction);

// Option 2: Subscription via lambda
var subscription2 = eventAggregator.Subscribe<MyMessage>(message => { /*...*/ });

The clients get an ISubscription<TMessage> in return, from which they’re able to unsubscribe:

// Option 1: Unsubscribe by calling the event aggregator method
eventAggregator.UnSubscribe(subscription);

// Option 2: Unsubscribe by calling Dispose() on the subscription object
subscription.Dispose();

Other clients now are able to publish concrete messages and subscribers get informed about those messages:

eventAggregator.Publish(new MyMessage{ /*...*/ });

How to get an instance of IEventAggregator, you may ask? Well, that’s your decision! Implement a singleton for accessing an instance, use your favorite DI container, whatever…

Conclusion

That’s it. A simple message-based event aggregator implementation that can be used in a variety of situations. And which can be replaced by other implementations as well. Perhaps you want to persist or log messages, enable detached subscribers, allow async event processing or even further functionality like load balancing… It’s up to you to provide your own implementation. And feel free to connect the Latch Pattern 😉

While the presented EventAggregator perfectly fitted my needs, it’s not intended to be universally applicable. For example I know that Prism uses WeakReferences to simplify garbage collection. I say it again: feel free to do that in your own implementation. Besides there are many more syntactic ways to implement event aggregators/brokers. Paste your comments if you have further suggestions – you’re welcome!

kick it on DotNetKicks.com

The Property Memento pattern

Edit: Find an improved implementation of the pattern here.
Edit
: Find an explicit implementation of the pattern here.

This blog post shows the Property Memento as pattern for storing property values and later restoring from those. Constructive feedback is welcome everytime!

Problem description

It’s a common task in several scenarios: you want to store the value of an object’s property, then temporarily change it to perform some actions and at the end restore the original property value again. Especially with UI-related task you come into this situation quite often.

The last time I came across with this requirement is only some days/weeks ago and was a UI task as well. I created a generic detail view in WinForms, which was built up by Reflection from an object’s properties and optional metadata information. This form contained a control for the object’s values on the one side and a validation summary control for showing validation messages on the other side. The validation summary had to change its content and layout dynamically while performing validation.

Through the dynamic nature of the form unfortunately I couldn’t use the AutoSize feature and thus had to layout the control manually (calculating and setting control sizes etc.). But I still wanted to use some AutoSize functionality, at least for the validation summary. And here’s the deal: everytime the validation messages on the summary change, the control should AutoSize to fit its content. With the new size I recalculate the Height of the whole form. This task can be done by manually setting the AutoSize property temporarily. Additionally it’s necessary to temporarily set the Anchor property of the details control and the validation summary to complete the layouting process correctly.

Normally in the past I would have used a manual approach like this:

private void SomeMethod(...)
{
    int oldValSumHeight = _valSum.Height;
    int newValSumHeight = 0;

    bool oldValSumAutoSize = _valSum.AutoSize;
    AnchorStyles oldValSumAnchor = _valSum.Anchor;
    AnchorStyles oldDetailAnchor = _detailContent.Anchor;

    _valSum.AutoSize = true;
    _valSum.Anchor = AnchorStyles.Left | AnchorStyles.Top;
    _detailContent.Anchor = AnchorStyles.Left | AnchorStyles.Top;

    _valSum.SetValidationMessages(validationMessages);

    newValSumHeight = _valSum.Height;
    Height = Height - oldValSumHeight + newValSumHeight;

    _valSum.AutoSize = oldValSumAutoSize;
    _valSum.Anchor = oldValSumAnchor;
    _detailContent.Anchor = oldDetailAnchor;

    _valSum.Height = newValSumHeight;
}

What a verbose and dirty code for such a simple task! Saving the old property values, setting  the new values, performing some action and restoring the original property values… It’s even hard to find out the core logic of the method. Oh dear! While this solution works, it has a really poor readability. Moreover it’s not dealing with exceptions that could occur when actions are performed in between. Thus the UI could be left in an inconsistently layouted state and presented to the user in this way. What a mess! But what’s the alternative?

The Property Memento

Better solution? What do you think about that (edit: find a better implementation here):

private void SomeMethod(...)
{
    int oldValSumHeight = _valSum.Height;
    int newValSumHeight = 0;

    using (GetAutoSizeMemento(_valSum, true))
    using (GetAnchorMemento(_valSum, AnchorStyles.Top|AnchorStyles.Left))
    using (GetAnchorMemento(_detailContent, AnchorStyles.Top|AnchorStyles.Left))
    {
        _valSum.SetValidationMessages(validationMessages);

        newValSumHeight = _valSum.Height;
        Height = Height - oldValSumHeight + newValSumHeight;
    }

    _valSum.Height = newValSumHeight;
}

private PropertyMemento<Control, bool> GetAutoSizeMemento(
    Control control, bool tempValue)
{
    return new PropertyMemento<Control, bool>(
        control, () => control.AutoSize, tempValue);
}

private PropertyMemento<Control, AnchorStyles> GetAnchorMemento(
    Control control, AnchorStyles tempValue)
{
    return new PropertyMemento<Control, AnchorStyles>(
        control, () => control.Anchor, tempValue);
}

Notice that the logic of SomeMethod() is exactly the same as in the first code snippet. But now the responsibility of storing and restoring property values is encapsulated in Memento objects which are utilized inside a using(){ } statement. GetAutoSizeMemento() and GetAnchorMemento() are just two simple helper methods to create the Memento objects, which support readability in this blog post, but nothing more…

So how is the Property Memento working conceptually? On creation of the Property Memento it stores the original value of an object’s property. Optionally it’s possible to set a new temporary value for this property as well. During the lifetime of the Property Memento the value of the property can be changed by a developer. Finally when Dispose() is called on the Property Memento, the initial property value is restored. Thus the Property Memento clearly encapsulates the task of storing and restoring property values.

The technical implementation of the Property Memento in C# uses Reflection and is shown below (edit: find a better implementation here):

public class PropertyMemento<TClass, TProperty> : IDisposable
    where TClass : class
{
    private readonly TProperty _originalPropertyValue;
    private readonly TClass _classInstance;
    private readonly Expression<Func<TProperty>> _propertySelector;

    public PropertyMemento(TClass classInstance,
        Expression<Func<TProperty>> propertySelector)
    {
        _classInstance = classInstance;
        _propertySelector = propertySelector;
        _originalPropertyValue =
            ReflectionHelper.GetPropertyValue(classInstance, propertySelector);
    }

    public PropertyMemento(TClass memberObject,
        Expression<Func<TProperty>> memberSelector, TProperty tempValue)
        : this(memberObject, memberSelector)
    {
        SetPropertyValue(tempValue);
    }

    public void Dispose()
    {
        SetPropertyValue(_originalPropertyValue);
    }

    private void SetPropertyValue(TProperty value)
    {
        ReflectionHelper.SetPropertyValue(
            _classInstance, _propertySelector, value);
    }
}

This implementation uses the following ReflectionHelper class:

static class ReflectionHelper
{
    public static PropertyInfo GetProperty<TEntity, TProperty>(
        Expression<Func<TProperty>> propertySelector)
    {
        return GetProperty<TEntity>(GetPropertyName(propertySelector));
    }

    public static PropertyInfo GetProperty<T>(string propertyName)
    {
        var propertyInfos = typeof(T).GetProperties();
        return propertyInfos.First(pi => pi.Name == propertyName);
    }

    public static string GetPropertyName<T>(
        Expression<Func<T>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        return memberExpression.Member.Name;
    }

    public static TProperty GetPropertyValue<TEntity, TProperty>(
        TEntity entity, Expression<Func<TProperty>> propertySelector)
    {
        return (TProperty)GetProperty<TEntity, TProperty>(propertySelector)
            .GetValue(entity, null);
    }

    public static void SetPropertyValue<TEntity, TProperty>(TEntity entity,
        Expression<Func<TProperty>> propertySelector, TProperty value)
    {
        GetProperty<TEntity, TProperty>(propertySelector)
            .SetValue(entity, value, null);
    }
}

As you can see, the Property Memento implementation is no rocket science. The constructor gets the class instance and an Expression which selects the property from this instance. Optionally you can provide a property value that should be set temporarily in place of the original value. Getting and setting the property value is done via the ReflectionHelper class. For the sake of shortness the implementation doesn’t have a good error handling mechanism. You could employ your own checks if you want. What I like is the use of generics. This eliminates many error sources and guides a developer with the usage of the Property Memento.

Really a pattern and a Memento?

I’ve used the Property Memento now in several different situations with success and thus I think it’s justified to call it a pattern.

But is it a Memento as well? Wikipedia says about the Memento pattern:

„The memento pattern is a software design pattern that provides the ability to restore an object to its previous state […]“

And this is true for the Property Memento, where the „object“ equals a property value on a class instance! The „previous state“ is stored on creation of the Memento and „restore an object“ is done on call of Dispose().

Finally

This blog post has shown the Property Memento as pattern for storing original property values and later on restoring them.

Compared to the „manual way“ the Property Memento has valuable advantages. It encapsulates the responsibility of storing an original value and restoring it when the using() block is finished. Client code remains clean and is condensed to the core logic, while delegating responsibilities to the Property Memento by an explicit using(){ } block. Thus the code becomes much more concise and readable. Last but not least the Property Memento employs an automatic exception handling mechanism. If an exception occurs inside a using() block of the Property Memento, finally the Dispose() method is called. Thus the Property Memento restores the original property state even in exceptional situations and the user gets a consistent layouted UI.

kick it on DotNetKicks.com

Latch me if you can!

In my first blog post I’ve shown a common UI problem when it comes to event handling and programmatic vs. user-triggered events on the one handside and to infinite loops due to recursive event chains on the other. With event detach/attach and boolean flags I’ve shown two simple solutions which are very common in many development projects. But they have their shortcomings and just don’t feel natural. This blog post shows an alternative which I found simple and beautiful.

Latch to the rescue

Jeremy Miller introduced the Latch design pattern as possible solution for the problem at hand. It’s a tiny beautiful, yet little know solution and the latter is a pitty. A Latch encapsulates the logic of executing an action depending on the current state of the Latch. If the Latch is in „Latched“ state, no action is executed. And actions can be executed inside of the Latch (changing the state to „Latched“), preventing other actions from executing.

Latch #1: Disposing Latch

Before reading Jeremy’s post, I’ve made a sort of Latch pattern for myself. Here the Latch implements IDisposable, and the Latched state is set on creation of the Latch and reset at a call of Dispose(). This allows the application of the using() { } syntax and the Latch state is reset automatically when exceptions occur. The Latch class would look like this:

public class Latch : IDisposable
{
    public bool IsLatched { get; private set; }

    public Latch()
    {
        IsLatched = true;
    }

    public void RunIfNotLatched(Action action)
    {
        if (IsLatched)
            return;

        action();
    }

    public void Dispose()
    {
        IsLatched = false;
    }

    public static Latch Latched
    {
        get { return new Latch(); }
    }
    public static Latch UnLatched
    {
        get { return new Latch { IsLatched = false }; }
    }
}

The RunIfNotLatched() method is just a little helper which executes an action given on the current state of the Latch. The actual application of the Latch in the example code from the previous post is shown here:

public partial class SomeControl : UserControl
{
    // ...

    private Latch _textSetByCodeLatch = Latch.UnLatched;

    private ViewData _viewData;
    public ViewData ViewData
    {
        get { return _viewData; }
        set
        {
            _viewData = value;
            if (value != null)
            {
                using (_textSetByCodeLatch = new Latch())
                {
                    _someTextBox.Text = value.SomeValue;
                }
                // other operations
            }
        }
    }

    private void OnSomeTextBoxTextChanged(object sender, EventArgs e)
    {
        _textSetByCodeLatch.RunIfNotLatched(() =>
        {
            // perform data/view update operations
        });
    }
}

At first sight I liked the using() { } syntax. It frees the application code from manually reseting the Latch to UnLatched state. At second sight I think there could be a cleaner solution. In my Latch implementation the using() { } syntax is kind of misused and could lead to irritations because there is implicit knowledge about the internal functionality of the Latch. Again, the intent is not explicitly revealed.

Latch #2: Boolean Latch

A cleaner solution with explicit methods for running actions inside of the Latch and missing action execution when other actions have entered the Latch could be the following Latch implementation:

public class Latch
{
    public bool IsLatched { get; private set; }

    public void RunLatched(Action action)
    {
        try
        {
            IsLatched = true;
            action();
        }
        finally
        {
            IsLatched = false;
        }
    }

    public void RunIfNotLatched(Action action)
    {
        if (IsLatched)
            return;

        action();
    }
}

Here the basic boolean logic behind matches with the Disposing Latch, but the syntax has changed. The Latch now contains two methods. RunLatched() executes an action inside the Latch and prevents actions from being executed in RunIfNotLatched(). Here’s the usage for this Latch type in our example:

public partial class SomeControl : UserControl
{
    // ...

    private readonly Latch _textSetByCodeLatch = new Latch();

    private ViewData _viewData;
    public ViewData ViewData
    {
        get { return _viewData; }
        set
        {
            _viewData = value;
            if (value != null)
            {
                _textSetByCodeLatch.RunLatched(() =>
                {
                    _someTextBox.Text = value.SomeValue;
                });
                // other operations
            }
        }
    }

    private void OnSomeTextBoxTextChanged(object sender, EventArgs e)
    {
        _textSetByCodeLatch.RunIfNotLatched(() =>
        {
            // perform data/view update operations
        });
    }
}

Now the Latch has a cleaner and more explicit syntax. And like the Disposing Latch it has a clean exception handling mechanism. That’s the good news. With that our Boolean Latch is applicable in most simple scenarios. But not in all! Imagine parallel execution of UI actions. Moreover imagine having two actions which should be run in RunLatched() of the same Latch object – again in parallel:

  1. Action 1 enters RunLatched() and the Latch changes its state.
  2. Action 2 enters RunLatched(), the Latch state remains in IsLatched.
  3. Action 1 leaves RunLatched() and the Latch changes its state to not latched.

Step 3 is the problem. Action 2 is still running inside the Latch, but due to the boolean logic the Latch is not latched any longer. Thus other actions are executed when given to RunIfNotLatched(), which is no help on the initial problem. This is not only true for the Boolean Latch, but for the Disposing Latch as well.

Latch #3: Counting Latch

This problem is solved by the Counting Latch, which is most similar to Jeremy’s Latch implementation. Instead of having just a boolean discriminator, it employs a counter for parallel RunLatched() calls. The IsLatched state is determined based on this counter. If it’s equal to 0, the Latch is not latched (because no method is currently running inside of RunLatched()). Else the Latch is treat as latched. Here’s the implementation of this Latch variant (edit: thanks nwiersma for the thread-safe hint):

public class Latch
{
    private readonly object _counterLock = new object();

    public int LatchCounter { get; private set; }

    public bool IsLatched
    {
        get { return (LatchCounter > 0); }
    }

    public void RunLatched(Action action)
    {
        try
        {
            lock(_counterLock) { LatchCounter++; }
            action();
        }
        finally
        {
            lock(_counterLock) { LatchCounter--; }
        }
    }

    public void RunIfNotLatched(Action action)
    {
        if (IsLatched)
            return;

        action();
    }
}

The usage in this case is equivalent to the Boolean Latch. You should note that each of these Latch implementations works, it’s just a matter of your requirements which of them you want to use. The Counting Latch as most generic Latch implementation above and applies to most situations.

Benefits of using the Latch

Using the Latch for the foresaid problems has clear advantages over the use of event detach/attach and boolean flags. First the Latch encapsulates the logic of running actions depending on a state, in this case the current execution of another action. Thus the purpose of a Latch is explicit, in contrast to the implicit intent of e.g. boolean flags. This increases code readability.

The second advantage comes with resetting the initial state. The Latch performs this task itself when an action leaves the RunLatched() method for example. With boolean flags and event detach/attach this is your task. It’s most likely getting problematic if exceptions are thrown inside an action. The Latch takes over the responsibility of automatically rolling back the state of the Latch on occurrence of an exception.

In conclusion the Latch is a pretty simple design pattern which increases readability and feels right for the problem of dependent action execution. For myself, at least I’ve found some nice solution for UI event reaction depending on the source of the trigger of the event and for infinite event loops, without relying on ugly boolean flags or event attach/detach.

kick it on DotNetKicks.com