Side effects
No edit summary
No edit summary
Line 1: Line 1:
This article describes how to catch changes to singlelinks as they evolve in MDrivenFramework.
This article describes how to catch changes to singlelinks as they evolve in MDrivenFramework.


From time to time, you want to have side effects trigger when changing something in the objects. There are many valid reasons why this occurs – but it is not always the best way to solve things (just a heads up that you should stay declarative in your thinking and always think twice when your development starts to look reactive as side effects are a typical example of this).
From time to time, you want to have side effects trigger when changing something in the objects. There are many valid reasons why this occurs – but it is not always the best way to solve things (just a heads up: you should stay declarative in your thinking and always think twice when your development starts to look reactive as side effects are a typical example of this).


I explained the HasUserCode property [[What about HasUserCode in Enterprise Core Objects – MDriven Framework|in a previous article]] that covers side effects on attributes, but what if you need side effects when your associations have changed?
I explained the HasUserCode property [[What about HasUserCode in Enterprise Core Objects – MDriven Framework|in a previous article]] that covers side effects on attributes, but what if you need side effects when your associations have changed?
Line 11: Line 11:
This new way is based on the ability to hook the objects cache of ECO (useable for a lot of advanced stuff).
This new way is based on the ability to hook the objects cache of ECO (useable for a lot of advanced stuff).


When one hooks the objects cache, one must be careful – every single state change of domain objects will be managed by the cache – anything extra you do here may affect the system performance. (I do not want to scare you – I am just saying.) You will not notice anything – unless you make an error.
When one hooks the objects cache, one must be careful – every single state change of domain objects will be managed by the cache. Anything extra you do here may affect the system performance. (I do not want to scare you – I am just saying.) You will not notice anything – unless you make an error.


We decided if you want to use this particular cache hook, it should be an option. You must “turn it on” in order to perform side effects on association changes.
We decided if you want to use this particular cache hook, it should be an option. You must “turn it on” in order to perform side effects on association changes.


This is how you turn it on - add this line early in your EcoSpace code:
This is how you turn it on - add this line early in your EcoSpace code:<blockquote>new LinkOperationCache(FrontsidePolicy) { Enabled = true }</blockquote><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:124aec2e-89b6-4fb2-b4ef-4f698712bfbd" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> EcoProject1EcoSpace() : <span style="color:#0000ff">base</span>()</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">this</span>.InitializeComponent();</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">new</span> <span style="color:#2b91af">LinkOperationCache</span>(FrontsidePolicy) { Enabled = <span style="color:#0000ff">true</span> };</li> <li>}</li> </ol> </div> </div> </div>Given this example model:
 
new LinkOperationCache(FrontsidePolicy) { Enabled = true }
 
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:124aec2e-89b6-4fb2-b4ef-4f698712bfbd" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> EcoProject1EcoSpace() : <span style="color:#0000ff">base</span>()</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">this</span>.InitializeComponent();</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">new</span> <span style="color:#2b91af">LinkOperationCache</span>(FrontsidePolicy) { Enabled = <span style="color:#0000ff">true</span> };</li> <li>}</li> </ol> </div> </div> </div>Given this example model:
[[File:Side effects -1.png|none|thumb|458x458px]]
[[File:Side effects -1.png|none|thumb|458x458px]]


We can now use the two interfaces involved, IMultiLinkCatcher and ISingleLinkCatcher, in code:<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:369c56f4-d973-4e13-a258-611540bd4dd5" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Class1</span>:<span style="color:#2b91af">IMultiLinkCatcher</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;</li> <li style="background: #f3f3f3">  <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> MultiLinkModified(<span style="color:#2b91af">IAssociationEnd</span> ae)</li> <li>  {</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">int</span> newcount=(<span style="color:#0000ff">this</span>.AsIObject().Properties[ae] <span style="color:#0000ff">as</span> <span style="color:#2b91af">IObjectList</span>).Count;</li> <li>    System.Diagnostics.<span style="color:#2b91af">Trace</span>.WriteLine(<span style="color:#a31515">&quot;User changed the multilink &quot;</span> +ae.Owner.Name+<span style="color:#a31515">&quot;.&quot;</span>+ae.Name + </li> <li style="background: #f3f3f3">            <span style="color:#a31515">&quot;. It now has &quot;</span>+newcount.ToString()+ <span style="color:#a31515">&quot; objects, check single link end for details&quot;</span>);</li> <li>  }</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>And</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c66318ce-3fa8-4441-86c9-c1d524657e3d" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Class2</span>:<span style="color:#2b91af">ISingleLinkCatcher</span></li> <li style="background: #f3f3f3">{</li> <li>  <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> SingleLinkModified(<span style="color:#2b91af">IAssociationEnd</span> ae, <span style="color:#2b91af">IEcoObject</span> oldValue, <span style="color:#2b91af">IEcoObject</span> newValue)</li> <li style="background: #f3f3f3">  {</li> <li>      <span style="color:#0000ff">string</span> oldvaluestr=<span style="color:#a31515">&quot;null&quot;</span>;</li> <li style="background: #f3f3f3">      <span style="color:#0000ff">string</span> newvaluestr=<span style="color:#a31515">&quot;null&quot;</span>;</li> <li>      <span style="color:#0000ff">if</span> (oldValue!=<span style="color:#0000ff">null</span> &amp;&amp; !oldValue.IsNull())</li> <li style="background: #f3f3f3">        oldvaluestr=oldValue.ToString();</li> <li>      <span style="color:#0000ff">if</span> (newValue != <span style="color:#0000ff">null</span> &amp;&amp; !newValue.IsNull())</li> <li style="background: #f3f3f3">        newvaluestr=newValue.ToString();</li> <li>      System.Diagnostics.<span style="color:#2b91af">Trace</span>.WriteLine(<span style="color:#a31515">&quot;User changed value on Singlelink &quot;</span> +ae.Owner.Name+<span style="color:#a31515">&quot;.&quot;</span>+ae.Name +</li> <li style="background: #f3f3f3">        <span style="color:#a31515">&quot; from &quot;</span> + oldvaluestr + <span style="color:#a31515">&quot; to &quot;</span> + newvaluestr);</li> <li>  } </li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div>
We can now use the two interfaces involved, IMultiLinkCatcher and ISingleLinkCatcher, in code:<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:369c56f4-d973-4e13-a258-611540bd4dd5" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Class1</span>:<span style="color:#2b91af">IMultiLinkCatcher</span></li> <li style="background: #f3f3f3">{</li> <li>&nbsp;</li> <li style="background: #f3f3f3">  <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> MultiLinkModified(<span style="color:#2b91af">IAssociationEnd</span> ae)</li> <li>  {</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">int</span> newcount=(<span style="color:#0000ff">this</span>.AsIObject().Properties[ae] <span style="color:#0000ff">as</span> <span style="color:#2b91af">IObjectList</span>).Count;</li> <li>    System.Diagnostics.<span style="color:#2b91af">Trace</span>.WriteLine(<span style="color:#a31515">&quot;User changed the multilink &quot;</span> +ae.Owner.Name+<span style="color:#a31515">&quot;.&quot;</span>+ae.Name + </li> <li style="background: #f3f3f3">            <span style="color:#a31515">&quot;. It now has &quot;</span>+newcount.ToString()+ <span style="color:#a31515">&quot; objects, check single link end for details&quot;</span>);</li> <li>  }</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>And:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c66318ce-3fa8-4441-86c9-c1d524657e3d" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 14pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Class2</span>:<span style="color:#2b91af">ISingleLinkCatcher</span></li> <li style="background: #f3f3f3">{</li> <li>  <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> SingleLinkModified(<span style="color:#2b91af">IAssociationEnd</span> ae, <span style="color:#2b91af">IEcoObject</span> oldValue, <span style="color:#2b91af">IEcoObject</span> newValue)</li> <li style="background: #f3f3f3">  {</li> <li>      <span style="color:#0000ff">string</span> oldvaluestr=<span style="color:#a31515">&quot;null&quot;</span>;</li> <li style="background: #f3f3f3">      <span style="color:#0000ff">string</span> newvaluestr=<span style="color:#a31515">&quot;null&quot;</span>;</li> <li>      <span style="color:#0000ff">if</span> (oldValue!=<span style="color:#0000ff">null</span> &amp;&amp; !oldValue.IsNull())</li> <li style="background: #f3f3f3">        oldvaluestr=oldValue.ToString();</li> <li>      <span style="color:#0000ff">if</span> (newValue != <span style="color:#0000ff">null</span> &amp;&amp; !newValue.IsNull())</li> <li style="background: #f3f3f3">        newvaluestr=newValue.ToString();</li> <li>      System.Diagnostics.<span style="color:#2b91af">Trace</span>.WriteLine(<span style="color:#a31515">&quot;User changed value on Singlelink &quot;</span> +ae.Owner.Name+<span style="color:#a31515">&quot;.&quot;</span>+ae.Name +</li> <li style="background: #f3f3f3">        <span style="color:#a31515">&quot; from &quot;</span> + oldvaluestr + <span style="color:#a31515">&quot; to &quot;</span> + newvaluestr);</li> <li>  } </li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div>
[[Category:MDriven Framework]]
[[Category:MDriven Framework]]
[[Category:Advanced]]
[[Category:Advanced]]

Revision as of 05:43, 12 July 2023

This article describes how to catch changes to singlelinks as they evolve in MDrivenFramework.

From time to time, you want to have side effects trigger when changing something in the objects. There are many valid reasons why this occurs – but it is not always the best way to solve things (just a heads up: you should stay declarative in your thinking and always think twice when your development starts to look reactive as side effects are a typical example of this).

I explained the HasUserCode property in a previous article that covers side effects on attributes, but what if you need side effects when your associations have changed?

In earlier versions, in ECO, we offered HasUserCode on associations but it turned out to be a bad solution – there were too many ways to make an association change (it has two ends to start with) to make the HasUserCode-approach execute correctly in every case.

Instead, we introduced a new way to handle side effects on associations, a way that works consistently – every time – no matter which end of the association your code touched – the side effect code will trigger.

This new way is based on the ability to hook the objects cache of ECO (useable for a lot of advanced stuff).

When one hooks the objects cache, one must be careful – every single state change of domain objects will be managed by the cache. Anything extra you do here may affect the system performance. (I do not want to scare you – I am just saying.) You will not notice anything – unless you make an error.

We decided if you want to use this particular cache hook, it should be an option. You must “turn it on” in order to perform side effects on association changes.

This is how you turn it on - add this line early in your EcoSpace code:

new LinkOperationCache(FrontsidePolicy) { Enabled = true }

  1. public EcoProject1EcoSpace() : base()
  2. {
  3.     this.InitializeComponent();
  4.     new LinkOperationCache(FrontsidePolicy) { Enabled = true };
  5. }

Given this example model:

Side effects -1.png

We can now use the two interfaces involved, IMultiLinkCatcher and ISingleLinkCatcher, in code:

  1. public partial class Class1:IMultiLinkCatcher
  2. {
  3.  
  4.   public void MultiLinkModified(IAssociationEnd ae)
  5.   {
  6.     int newcount=(this.AsIObject().Properties[ae] as IObjectList).Count;
  7.     System.Diagnostics.Trace.WriteLine("User changed the multilink " +ae.Owner.Name+"."+ae.Name +
  8.             ". It now has "+newcount.ToString()+ " objects, check single link end for details");
  9.   }
  10. }

And:

  1. public partial class Class2:ISingleLinkCatcher
  2. {
  3.   public void SingleLinkModified(IAssociationEnd ae, IEcoObject oldValue, IEcoObject newValue)
  4.   {
  5.       string oldvaluestr="null";
  6.       string newvaluestr="null";
  7.       if (oldValue!=null && !oldValue.IsNull())
  8.         oldvaluestr=oldValue.ToString();
  9.       if (newValue != null && !newValue.IsNull())
  10.         newvaluestr=newValue.ToString();
  11.       System.Diagnostics.Trace.WriteLine("User changed value on Singlelink " +ae.Owner.Name+"."+ae.Name +
  12.         " from " + oldvaluestr + " to " + newvaluestr);
  13.   }
  14. }
This page was edited 122 days ago on 01/11/2024. What links here