<span id="Label3"></p><p><p></p></p><p><p>The <strong>eXpressApp Framework</strong> is based on the modules Concept. As a rule, every module implements a certain feature. Entities implemented in a module, such as persistent classes or extra application Model Nodes-can is customized by users Of the application via the Model Editor. Such customizations is saved as application Model differences in Xafml files. Legacy application Model differences might pose a problem when a module was updated to a new version, and its internal stru Cture is Changed. so, developers implementing modules should provide means to convert application Model differences with new Versions. The <strong>eXpressApp Framework</strong>provides easy ways to implement such converters. This topic describes Them.</p></p><p><p>basically, application Model differences is converted in and steps.</p></p> <ol> <ol> <li>The xafml files stored in XML format can is processed by a module implementing the Imodelxmlconverter Interface. This step allows the Application-to-start correctly, where otherwise, legacy application Model differences would cause an Exception at the application Start. In simple conversion scenarios, This may is the only required Step.</li> <li>For complex conversion scenarios, Special updaters implementing the Imodelnodeupdater<t> interface should is Used. Such Updaters can perform much more versatile conversions.</li> </ol> </ol><p><p>Depending on a particular scenario, the need to perform either both of these steps or just ONE. so, for example, in one scenario-need to implement a XML converter, so, the application could start, and a No De updater, to perform a complex conversion. In the other scenarios, the need to implement only a XML converter or a node updater.</p></p>Implement an XML Converter<p><p></p></p><p><p>An XML converter are represented by a module implementing the Imodelxmlconverter Interface. The interface declares the Imodelxmlconverter.convertxml method, which is invoked for each node customized in application Model Differences. The method takes the Convertxmlparameters object, supplying differences as a parameter. You can handle changes to a node in the Method's body, by converting differences and making them correspond to the actual Model. Consider the following example.</p></p><p><p>Suppose your application uses a module which adds an <strong>operatingmode</strong> string property to the application Model ' s Opt Ions Node. This property was designed to take either a "simple" or "Complex" word as a Value. originally, the module extends the application Model in the following to:</p></p> <table id="dxTab9" class="dx-tabs"> <tbody> <tr> <td> <table id="dxtab9_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active"> C # </td> <td class="dx-tabs-header">vb </td> <td class="dx-tabs-filler"> </td> </tr> </tbody> </table></td> </tr> <tr> <td> <pre> <span class="cr-cs-keyword">using devexpress.expressapp.model;<span class="cr-cs-keyword"> Public <span class="cr-cs-keyword">interface imodelmyoptions{<span class="cr-cs-keyword">string Operatingmode {get; set;}} <span class="cr-cs-keyword">public <span class="cr-cs-keyword">sealed <span class="cr-cs-keyword"> Partial <span class="cr-cs-keyword">class mymodule:modulebase {<span class="cr-cs-comment">//... <span class="cr-cs-keyword">public <span class="cr-cs-keyword">override <span class="cr-cs-keyword">void Extendmodelinterfaces (modelinterfaceextenders extenders) {<span class="cr-cs-keyword">base. Extendmodelinterfaces (extenders); Extenders. add<imodeloptions, imodelmyoptions> (); }}</span></span></span></span></span></span></span></span></span></span></span></span></span></pre></td> </tr> </tbody> </table><p><p> Users of your application customize this property value and it are stored to their application Model Differences. then, the module was updated to a new version which introduces a couple of Changes. first, the <strong> operatingmode </strong> property type is changed to a newly introduced Enumeration. Second, string representations of the new enumeration values is different from the previously used string values: </p></p> <table id="dxTab10" class="dx-tabs"> <tbody> <tr> <td> <tbo dy> </tbo> <table id="dxtab10_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">c# </td> <td class="dx-tabs-header">vb </td> <td cl ass="dx-tabs-filler"> </td> </tr> </tbody> </table> </td> </tr> <tr> <td> <pre> <span class="cr-cs -keyword ">public <span class=" cr-cs-keyword ">interface imodelmyoptions {operatingmode OperatingMode {get; set; }}<span class="cr-cs-keyword">public <span class="cr-cs-keyword">enum operatingmode {Basic, advanced} </span> </span></span></span></pre></td> </tr> </tbody> </table><p><p>If you are recompile the application with the updated module and redistribute it, existing users would not is able to use T He Application. At the application start, a message would be displayed stating this an error have occurred while loading the application Mod El Differences. To avoid this, an XML converter should is implemented in the Module. The following code snippet illustrates a possible solution:</p></p> <table id="dxTab11" class="dx-tabs"> <tbody> <tr> <td> <table id="dxTab11_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">C#</td> <td class="dx-tabs-header">Vb</td> <td class="dx-tabs-filler"></td> </tr> </tbody> </table></td> </tr> <tr> <td><pre><span class="cr-cs-keyword">Using DevExpress.ExpressApp.Model;<span class="cr-cs-keyword">Using DevExpress.ExpressApp.Updating;<span class="cr-cs-keyword">Public<span class="cr-cs-keyword">Sealed<span class="cr-cs-keyword">Partial<span class="cr-cs-keyword">Class mymodule:modulebase, Imodelxmlconverter {<span class="cr-cs-comment">//...<span class="cr-cs-keyword">Public<span class="cr-cs-keyword">void Convertxml (convertxmlparameters Parameters) {<span class="cr-cs-keyword"><span class="cr-cs-keyword">if (<span class="cr-cs-keyword">typeof (imodeloptions). IsAssignableFrom (parameters. NodeType)) { <span class="cr-cs-keyword">string property = <span class="cr-cs-string">"operatingmode"; <span class="cr-cs-keyword">if (parameters. ContainsKey (property)) { <span class="cr-cs-keyword">String value = Parameters. values[property]; <span class="cr-cs-keyword">if (! enum.isdefined (<span class="cr-cs-keyword">typeof (operatingmode), Value)) { <span class="cr-cs-keyword">switch (value). ToLower ()) { <span class="cr-cs-keyword">case <span class="cr-cs-string">"complex": Parameters. values[property] = OperatingMode.Advanced.ToString (); break <span class="cr-cs-keyword">; <span class="cr-cs-keyword">Default:parameters. values[property] = OperatingMode.Basic.ToString (); break <span class="cr-cs-keyword">;} } } } }}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre></td> </tr> </tbody> </table><p><p>The converter checks whether the currently processed node is the Options Node. If It is, the converter checks whether the <strong>Operatingmode</strong> property has a legacy Value. then, the ' Complex ' value becomes <strong>operatingmode.advanced</strong> and all other values become <strong>OPERATINGMODE.BASIC.</strong></p></p><p><p>now, the consider another very common scenario when a Node's property is Renamed. suppose, a <strong>Mode</strong> property declared in the Options node is renamed to <strong>Operatingmode</strong>. The following code snippet illustrates a possible XML converter:</p></p> <table id="dxTab12" class="dx-tabs"> <tbody> <tr> <td> <table id="dxTab12_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">C#</td> <td class="dx-tabs-header">Vb</td> <td class="dx-tabs-filler"></td> </tr> </tbody> </table></td> </tr> <tr> <td><pre><span class="cr-cs-keyword">Using DevExpress.ExpressApp.Model;<span class="cr-cs-keyword">Using DevExpress.ExpressApp.Updating;<span class="cr-cs-keyword"><span class="cr-cs-keyword">public <span class="cr-cs-keyword">Sealed <span class="cr-cs-keyword">partial <span class="cr-cs-keyword">class mymodule:modulebase, Imodelxmlconverter { <span class="cr-cs-comment">//... <span class="cr-cs-keyword">public <span class="cr-cs-keyword">void Convertxml (convertxmlparameters Parameters) { <span class="cr-cs-keyword">if (<span class="cr-cs-keyword">typeof (imodeloptions). IsAssignableFrom (parameters. NodeType)) { <span class="cr-cs-keyword">string oldproperty = <span class="cr-cs-string">"Mode"; <span class="cr-cs-keyword">string newproperty = <span class="cr-cs-string">"operatingmode"; <span class="cr-cs-keyword">if (parameters. ContainsKey (oldproperty)) {parameters. values[newproperty] = Parameters. values[oldproperty]; Parameters. Values.remove (oldproperty); } } }}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre></td> </tr> </tbody> </table><p><p>As illustrated by the examples, an XML converter works with one node at a Time. so, complex conversions, affecting several nodes at once, is not possible. In these cases, special updaters implementing the Imodelnodeupdater<t> interface should is Used.</p></p><p><p></p></p>Implement a Node Updater<p><p></p></p><p><p>A node updater is represented by a class implementing the Imodelnodeupdater<t> Interface. The generic type parameter specifies the type of the nodes for which the updater is Intended. The interface declares a single imodelnodeupdater<t>. Updatenode method, which takes, Parameters. The first parameter is the application Model node in process, represented by an object implementing the Imodelnode Interfa Ce. The second parameter is the Application's application Model, represented by an object, implementing the Imodelapplication Interface. Since you has access to the whole application Model, complex conversions affecting multiple nodes can be performed. Consider the following example.</p></p><p><p>Suppose your application uses a module which adds an <strong>operatingmode</strong> string property to the application Model ' s Opt Ions Node. originally, the interface extending the application Model looks like this:</p></p> <table id="dxTab13" class="dx-tabs"> <tbody> <tr> <td> <table id="dxTab13_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">C#</td> <td class="dx-tabs-header">Vb</td> <td class="dx-tabs-filler"></td> </tr> </tbody> </table></td> </tr> <tr> <td><pre><span class="cr-cs-keyword">Public <span class="cr-cs-keyword">Interface Imodelmyoptions { operatingmode operatingmode {get; set;}} public <span class="cr-cs-keyword"> <span class="cr-cs-keyword">enum Operatingmode {Basic, advanced}</span> </span> </span></span></pre></td> </tr> </tbody> </table><p><p>then, the module was updated to a new version which moves the property to a newly introduced child node:</p></p> <table id="dxTab14" class="dx-tabs"> <tbody> <tr> <td> <tbo dy> </tbo> <table id="dxtab14_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">c# </td> <td class="dx-tabs-header">vb </td> <td cl ass="dx-tabs-filler"> </td> </tr> </tbody> </table> </td> </tr> <tr> <td> <pre> <span class="cr-cs -keyword ">using DevExpress.ExpressApp.Model; <span class="cr-cs-keyword">public <span class="cr-cs-keyword">interface imodelmyoptions { Imodelchildoptions childoptions {get;}} <span class="cr-cs-keyword">public <span class="cr-cs-keyword">interface Imodelchildoptions:imodelnode { Operatingmode Operatingmode {get; set;}} <span class="cr-cs-keyword">public <span class="cr-cs-keyword">enum operatingmode {Basic, advanced} </span> </span></span></span></span></span></span></pre></td> </tr> </tbody> </table><p><p>If you are recompile the application with the updated module and redistribute it, the original <strong></strong> Operatingmode prop Erty values specified by users of the application would be Lost. To avoid this, a node updater should is Implemented. A possible place for the implementation is the updated module:</p></p> <table id="dxTab15" class="dx-tabs"> <tbody> <tr> <td> <table id="dxTab15_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">C#</td> <td class="dx-tabs-header">Vb</td> <td class="dx-tabs-filler"></td> </tr> </tbody> </table></td> </tr> <tr> <td><pre><span class="cr-cs-keyword">Using DevExpress.ExpressApp.Model;<span class="cr-cs-keyword"><span class="cr-cs-keyword">using DevExpress.ExpressApp.Model.Core; <span class="cr-cs-keyword">public <span class="cr-cs-keyword">sealed <span class="cr-cs-keyword"> Partial <span class="cr-cs-keyword">class mymodule:modulebase, imodelnodeupdater<imodeloptions> {<span class="cr-cs-comment">//... <span class="cr-cs-keyword">public <span class="cr-cs-keyword">void Updatenode (imodeloptions node, imodelapplication application) {<span class="cr-cs-keyword">string myProperty = <span class="cr-cs-keyword" and "operatingmode"; <span>if (node. HasValue (myproperty)) {<span class="cr-cs-keyword">string value = Node. Getvalue<<span class="cr-cs-keyword">string> (myproperty); node. ClearValue (myproperty); ((imodelmyoptions) node). Childoptions.operatingmode = (operatingmode) enum.parse (<span class="cr-cs-keyword">typeof (OperatingMode), value);}} }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre></td> </tr> </tbody> </table><p><p>The updater in the example checks whether the currently processed node have a legacy <strong>operatingmode</strong> Property Value. If There is such a value, it's assigned to the new <strong>Operatingmode</strong> property, and the Legacy property value is CLE Ared.</p></p><p><p>Note that since a node updater can is implemented anywhere in the application, the updater should is registered via the Mo Dulebase.addmodelnodeupdaters method:</p></p> <table id="dxTab16" class="dx-tabs"> <tbody> <tr> <td> <table id="dxTab16_tabs" class="dx-tabs-inner"> <tbody> <tr> <td class="dx-tabs-header dx-active">C#</td> <td class="dx-tabs-header">Vb</td> <td class="dx-tabs-filler"></td> </tr> </tbody> </table></td> </tr> <tr> <td><pre><span class="cr-cs-keyword">Using DevExpress.ExpressApp.Model; <span class="cr-cs-keyword">using DevExpress.ExpressApp.Model.Core; <span class="cr-cs-keyword">public <span class="cr-cs-keyword">Sealed <span class="cr-cs-keyword">partial <span class="cr-cs-keyword"><span class="cr-cs-comment"><span class="cr-cs-keyword">public <span class="cr-cs-keyword">override <span class="cr-cs-keyword"><span class="cr-cs-keyword">Base. Addmodelnodeupdaters (updaterregistrator); updaterregistrator.addupdater<imodeloptions> (this<span class="cr-cs-keyword">);}}</span> </span></span> </span> </span></span></span> </span> </span> </span> </span></span></pre></td> </tr> </tbody> </table><p><p>Convert Application Model Differences</p></p></span>
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service