Side effects
No edit summary
m ((username removed) (log details removed))
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
From time to time you want to have side effects trigger when changing something in the objects. There are many valid reasons for this to happen – 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 is a typical example of).
This article describes how to catch changes to singlelinks as they evolve in MDrivenFramework.


I explained the HasUserCode property in [[What about HasUserCode in Enterprise Core Objects – MDriven Framework|an article some time ago]] and that covers side effects on attributes, but what if you need side effects when your associations are changed?
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).


Actually in earlier versions in ECO we offered HasUserCode on associations but it turned out that it was not a good solution – there were too many ways to make a association change (it has two ends to start with) to make the HasUserCode-approach execute correctly in every case.
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?


So 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.
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.


This new way is based on the ability to hook the objects cache of ECO (useable for a lot advanced stuff).
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.  


When one hooks the objects cache one must be careful – every single state change of domain objects will be managed by the cache – so anything extra you do here will effect the system performance. I do not want to scare you – I am just saying. You will not notice anything – unless you do something bad.
This new way is based on the ability to hook the objects cache of ECO (useable for a lot of advanced stuff).


Anyway we decided that it should be an option if you want to use this particular cache hook or not. You must “turn it on” in order to perform side effects on association changes.
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.


This is how you turn it on, add this line early in your EcoSpace code :
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.


new LinkOperationCache(FrontsidePolicy) { Enabled = true }
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:
[[File:Side effects -1.png|none|thumb|458x458px]]


<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: 10pt"> <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>
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:Advanced]]

Latest revision as of 06:45, 11 January 2024

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 123 days ago on 01/11/2024. What links here