{"id":105,"date":"2004-04-29T14:47:11","date_gmt":"2004-04-29T04:47:11","guid":{"rendered":"http:\/\/www.malcolmgroves.com\/blog\/?p=105"},"modified":"2004-04-29T14:47:11","modified_gmt":"2004-04-29T04:47:11","slug":"derived-attributes-part-2-code-derived-attributes","status":"publish","type":"post","link":"http:\/\/www.malcolmgroves.com\/blog\/?p=105","title":{"rendered":"Derived Attributes Part 2 &#8211; Code Derived Attributes"},"content":{"rendered":"<p>Ok, so yesterday we looked at adding attributes to our ECO classes where the value of those attributes was calculated at runtime using OCL. If you haven&#8217;t already, look through the link I gave yesterday to <a href=\"http:\/\/www.viewpointsa.com\/bold_resources\/getting_started_with_bold\/Part3-OCL.html\">Anthony Richardson&#8217;s OCL Tutorial<\/a>, as it is possible to embed some fairly rich logic into your model using this language.<\/p>\n<p>That said, lets not kid ourselves. Delphi and C# are much richer languages than OCL, so there will come a time where either it&#8217;s not possible to calculate your attribute&#8217;s value using OCL, or where you are more comfortable doing it in code. So, let&#8217;s look at Code Derived Attributes.<\/p>\n<p>I&#8217;ve created a new class called Appointment, which has a Start attribute of type System.DateTime, which represents the start time of the Appointment and a Duration attribute of type Integer, which is the length of the Appointment in minutes. I&#8217;ve also then created a Derived Attribute called Finish, also of type System.DateTime. Just like yesterday, I&#8217;ve set its Derived property to True and its Persistence property to Transient. However, unlike yesterday, I have not specified any OCL to calculate the value.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.malcolmgroves.com\/images\/2004\/04\/29\/20040429001.gif\" \/><\/p>\n<p>When the ECO framework finds a derived attribute that has no OCL, it goes looking for a method, using reflection, of a particular signature and name, specifically:<\/p>\n<p>function &lt;Attribute Name&gt;DeriveAndSubscribe(reevaluateSubscriber, resubscribeSubscriber: ISubscriber): system.object;<\/p>\n<p>In this case, my attribute is called Finish, so it looks for a method called:<\/p>\n<p>function FinishDeriveAndSubscribe(reevaluateSubscriber, resubscribeSubscriber: ISubscriber): system.object;<\/p>\n<p>If it finds this method, it executes it, and uses the return value as the attribute&#8217;s value. So its your job inside this method to do whatever you need to calculate the attribute&#8217;s value. In my case, I want to add the Duration in minutes to my Start time, so my method looks like this:<\/p>\n<p>function Appointment.FinishDeriveAndSubscribe(reevaluateSubscriber, resubscribeSubscriber: ISubscriber): system.object;   <br \/>begin    <br \/>&#160; AsIObject.Properties[&#8216;Start&#8217;].SubscribeToValue(reevaluateSubscriber);    <br \/>&#160; AsIObject.Properties[&#8216;Duration&#8217;].SubscribeToValue(reevaluateSubscriber);    <br \/>&#160; result := Start.AddMinutes(Duration);    <br \/>end;<\/p>\n<p>Now hang on a sec, the last line makes sense, but what are the first two lines doing? <\/p>\n<p>Well, let&#8217;s step back a bit. ECO does not actually derive the value of your attribute every time someone asks for it. Instead it caches the value of the attribute after it is first calculated, and returns this cached value on subsequent requests, provided the attrbiute is not marked as out of date. How would our attribute get marked as out of date?&#160; Well, that&#8217;s where the first two lines of code above come in. We&#8217;ve subscribed to be notified whenever Start or Duration are changed. When we are notified, the ECO framework will flag our Finish attribute as out of date. Then, when the next request for its value is made, before the cached value is returned this flag will be checked and, the value of the atribute will be recalculated.<\/p>\n<p>Subscriptions in ECO are an important topic that I plan to cover in future posts, but in the meantime, make sure you subscribe to any other attributes on which you are depending.<\/p>\n<p>Not quite as easy as using OCL, but way more powerful, as you now have full access to the entire .NET Framework to use in calculating your attribute&#8217;s value.<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:0767317B-992E-4b12-91E0-4F059A8CECA8:989ceb70-f656-44b9-9c3b-7f1839164e01\" style=\"padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px\">Technorati Tags: <a href=\"http:\/\/technorati.com\/tags\/Delphi\" rel=\"tag\">Delphi<\/a>,<a href=\"http:\/\/technorati.com\/tags\/ECO\" rel=\"tag\">ECO<\/a>,<a href=\"http:\/\/technorati.com\/tags\/OCL\" rel=\"tag\">OCL<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Ok, so yesterday we looked at adding attributes to our ECO classes where the value of those attributes was calculated at runtime using OCL. If you haven&#8217;t already, look through the link I gave yesterday to Anthony Richardson&#8217;s OCL Tutorial, as it is possible to embed some fairly rich logic into your model using this [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-105","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=105"}],"version-history":[{"count":0,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/105\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=105"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}