{"id":1042,"date":"2010-09-12T04:00:20","date_gmt":"2010-09-12T03:00:20","guid":{"rendered":"http:\/\/www.minddriven.de\/?p=1042"},"modified":"2010-09-15T09:41:27","modified_gmt":"2010-09-15T08:41:27","slug":"explicit-property-memento","status":"publish","type":"post","link":"https:\/\/www.minddriven.de\/index.php\/technology\/development\/design-patterns\/explicit-property-memento","title":{"rendered":"Explicit Property Memento"},"content":{"rendered":"<h3>Introduction<\/h3>\n<p>Some weeks ago <a href=\"http:\/\/www.minddriven.de\/index.php\/technology\/development\/design-patterns\/property-memento-pattern\">I&#8217;ve introduced<\/a> the <strong>Property Memento pattern<\/strong> as solution for temporarily saving the state of an entity&#8217;s property on creation of the Property Memento and restoring this initial state when the Property Memento disposes. I&#8217;ve shown that the <code>using(){}<\/code> syntax separates between the Property Memento initialization and the core logic which should be run inside the Memento with temporarily changed property values.<\/p>\n<p>While I like the pattern and its usage, I see that the <code>using<\/code> syntax can be disturbing for developers who don&#8217;t know the internal implementation of the Property Memento. The implementation mixes <code>using<\/code> as common syntax with other semantics, which violates the <em>uniformity principle<\/em> of computer science.<\/p>\n<p>A <a href=\"http:\/\/svenerikmatzen.wordpress.com\/\" target=\"_blank\">colleague<\/a> suggested an implementation of the pattern, which makes the three steps in a Property Memento&#8217;s lifetime explicit:<\/p>\n<ol>\n<li><strong>Memorize<\/strong> the current properties values.<\/li>\n<li><strong>Invoke<\/strong> some actions.<\/li>\n<li><strong>Restore<\/strong> the memorized values.<\/li>\n<\/ol>\n<p>I&#8217;ve adopted his implementation to fit my needs of memorizing properties even for more than one entity.<\/p>\n<h3>Explicit Property Memento implementation<\/h3>\n<p>The implementation of the Explicit Property Memento projects the 3 steps of a Property Memento by the methods <code>Memorize()<\/code>, <code>Invoke()<\/code> and <code>RestoreValues()<\/code>. 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 <code>ExplicitPropertyMemento<\/code> 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&#8217;s the implementation part:<\/p>\n<pre class=\"brush:csharp\">public class ExplicitPropertyMemento\r\n{\r\n    class MemorizedProperty\r\n    {\r\n        public string Name { get; set; }\r\n        public object Value { get; set; }\r\n    }\r\n\r\n    private readonly IDictionary&lt;object, List&lt;MemorizedProperty&gt;&gt; _memorizedProperties\r\n        = new Dictionary&lt;object, List&lt;MemorizedProperty&gt;&gt;();\r\n\r\n    public static ExplicitPropertyMemento Create\r\n    {\r\n        get { return new ExplicitPropertyMemento(); }\r\n    }\r\n\r\n    public ExplicitPropertyMemento Memorize(\r\n        object classInstance, params Expression&lt;Func&lt;object&gt;&gt;[] propertySelectors)\r\n    {\r\n        if(propertySelectors == null)\r\n            return this;\r\n\r\n        var properties = new List&lt;MemorizedProperty&gt;();\r\n        foreach(var propertySelector in propertySelectors)\r\n        {\r\n            string propertyName = GetPropertyName(propertySelector);\r\n            properties.Add(new MemorizedProperty\r\n                {\r\n                    Name = propertyName,\r\n                    Value = GetPropertyValue(classInstance, propertyName)\r\n                });\r\n        }\r\n\r\n        if(_memorizedProperties.ContainsKey(classInstance))\r\n            _memorizedProperties[classInstance].AddRange(properties);\r\n        else\r\n            _memorizedProperties.Add(classInstance, properties);\r\n\r\n        return this;\r\n    }\r\n\r\n    public ExplicitPropertyMemento Memorize&lt;TProperty&gt;(object classInstance,\r\n        Expression&lt;Func&lt;object&gt;&gt; propertySelector, TProperty tempValue)\r\n    {\r\n        Memorize(classInstance, propertySelector);\r\n\r\n        string propertyName = GetPropertyName(propertySelector);\r\n        SetPropertyValue(classInstance, propertyName, tempValue);\r\n\r\n        return this;\r\n    }\r\n\r\n    public ExplicitPropertyMemento Invoke(Action action)\r\n    {\r\n        try\r\n        {\r\n            action.Invoke();\r\n        }\r\n        catch\r\n        {\r\n            RestoreValues();\r\n            throw;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    public void RestoreValues()\r\n    {\r\n        foreach(var memorizedEntity in _memorizedProperties)\r\n        {\r\n            object classInstance = memorizedEntity.Key;\r\n            foreach(var property in memorizedEntity.Value)\r\n                SetPropertyValue(classInstance, property.Name, property.Value);\r\n        }\r\n    }\r\n\r\n    private string GetPropertyName(Expression&lt;Func&lt;object&gt;&gt; propertySelector)\r\n    {\r\n        var body = propertySelector.Body;\r\n        if (body.NodeType == ExpressionType.Convert)\r\n            body = ((UnaryExpression)body).Operand;\r\n        return ((MemberExpression)body).Member.Name;\r\n    }\r\n\r\n    private object GetPropertyValue(object classInstance, string propertyName)\r\n    {\r\n        return classInstance\r\n            .GetType()\r\n            .GetProperty(propertyName)\r\n            .GetValue(classInstance, null);\r\n    }\r\n\r\n    private void SetPropertyValue(object classInstance, string propertyName, object value)\r\n    {\r\n        classInstance\r\n            .GetType()\r\n            .GetProperty(propertyName)\r\n            .SetValue(classInstance, value, null);\r\n    }\r\n}<\/pre>\n<h3>Usage example<\/h3>\n<p>The usage is explicitly projecting the Property Memento process by the methods <code>Memorize()<\/code>, <code>Invoke()<\/code> and <code>RestoreValues()<\/code> and it&#8217;s straightforward. In case of the <a href=\"http:\/\/www.minddriven.de\/index.php\/technology\/development\/design-patterns\/property-memento-pattern\" target=\"_blank\">introductory example<\/a> it&#8217;s shown next:<\/p>\n<pre class=\"brush:csharp\">private void SomeMethod(...)\r\n{\r\n    int oldValSumHeight = _valSum.Height;\r\n    int newValSumHeight = 0;\r\n\r\n    var newAnchor = AnchorStyles.Top | AnchorStyles.Left;\r\n    ExplicitPropertyMemento.Create\r\n        .Memorize(_valSum, () =&gt; _valSum.AutoSize, true)\r\n        .Memorize(_valSum, () =&gt; _valSum.Anchor, newAnchor)\r\n        .Memorize(_detailContent, () =&gt; _detailContent.Anchor, newAnchor)\r\n        .Invoke(() =&gt;\r\n            {\r\n                _valSum.SetValidationMessages(validationMessages);\r\n\r\n                newValSumHeight = _valSum.Height;\r\n                Height = Height - oldValSumHeight + newValSumHeight;\r\n            })\r\n        .RestoreValues();\r\n\r\n    _valSum.Height = newValSumHeight;\r\n}<\/pre>\n<p>Alternatively the <code>ExplicitPropertyMemento<\/code> implementation allows specifying more than one property as argument for the <code>Memorize()<\/code> method, if you don&#8217;t want to set the new property value directly by this method. Thus you could use some code like this:<\/p>\n<pre class=\"brush:csharp\">private void SomeMethod(...)\r\n{\r\n    int oldValSumHeight = _valSum.Height;\r\n    int newValSumHeight = 0;\r\n\r\n    ExplicitPropertyMemento.Create\r\n        .Memorize(_valSum, () =&gt; _valSum.AutoSize, () =&gt; _valSum.Anchor)\r\n        .Memorize(_detailContent, () =&gt; _detailContent.Anchor)\r\n        .Invoke(() =&gt;\r\n            {\r\n                _valSum.AutoSize = true;\r\n                _valSum.Anchor = AnchorStyles.Top | AnchorStyles.Left;\r\n                _detailContent.Anchor = AnchorStyles.Top | AnchorStyles.Left;\r\n\r\n                _valSum.SetValidationMessages(validationMessages);\r\n\r\n                newValSumHeight = _valSum.Height;\r\n                Height = Height - oldValSumHeight + newValSumHeight;\r\n            })\r\n        .RestoreValues();\r\n\r\n    _valSum.Height = newValSumHeight;\r\n}<\/pre>\n<h3>Conclusion<\/h3>\n<p>Instead of the <code>using<\/code> 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 <code>using<\/code> syntax because it&#8217;s very dense, but in terms of <em>intention revealing<\/em> I also like the <code>ExplicitPropertyMemento<\/code>. What&#8217;s your opinion? At least feel free to choose the implementation you prefer \ud83d\ude42<\/p>\n<p><a href=\"http:\/\/www.dotnetkicks.com\/kick\/?url=http%3a%2f%2fwww.minddriven.de%2f%3fp%3d1042\"><img decoding=\"async\" src=\"http:\/\/www.dotnetkicks.com\/Services\/Images\/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.minddriven.de%2f%3fp%3d1042\" border=\"0\" alt=\"kick it on DotNetKicks.com\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Some weeks ago I&#8217;ve introduced the Property Memento pattern as solution for temporarily saving the state of an entity&#8217;s property on creation of the Property Memento and restoring this initial state when the Property Memento disposes. I&#8217;ve shown that the using(){} syntax separates between the Property Memento initialization and the core logic which should &hellip; <a href=\"https:\/\/www.minddriven.de\/index.php\/technology\/development\/design-patterns\/explicit-property-memento\" class=\"more-link\"><span class=\"screen-reader-text\">Explicit Property Memento<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[264,151,268,267,277],"class_list":["post-1042","post","type-post","status-publish","format-standard","hentry","category-design-patterns","tag-design-pattern","tag-explicit","tag-memento","tag-property","tag-property-memento"],"_links":{"self":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1042","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/comments?post=1042"}],"version-history":[{"count":8,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1042\/revisions"}],"predecessor-version":[{"id":1065,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/1042\/revisions\/1065"}],"wp:attachment":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/media?parent=1042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/categories?post=1042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/tags?post=1042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}