Convert Application Model Differences
The eXpressApp Framework 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 be customized by users of the application via the Model Editor. Such customizations are saved as Application Model differences in XafML files. Legacy Application Model differences might pose a problem when a module is updated to a new version, and its internal structure is changed. So, developers implementing modules should provide means to convert Application Model differences with new versions. The eXpressApp Frameworkprovides easy ways to implement such converters. This topic describes them.
Basically, Application Model differences are converted in two steps.
- The XafML files stored in XML format can be 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 be the only required step.
- For complex conversion scenarios, special updaters implementing the IModelNodeUpdater<T> interface should be used. Such updaters can perform much more versatile conversions.
Depending on a particular scenario, you may need to perform either both of these steps or just one. So, for example, in one scenario you may need to implement an XML converter, so that the application could start, and a node updater, to perform a complex conversion. In other scenarios, you may need to implement only an XML converter or a node updater.
Implement an XML converter
An XML converter is 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.
Suppose your application uses a module which adds an OperatingMode string property to the Application Model's Options node. This property is designed to take either a "Simple" or "Complex" word as a value. Originally, the module extends the Application Model in the following way:
|
|||
using DevExpress.ExpressApp.Model;
public interface IModelMyOptions{
|
Users of your application customize this property value and it is stored to their Application Model differences. Then, the module is updated to a new version which introduces a couple of changes. First, the OperatingMode property type is changed to a newly introduced enumeration. Second, string representations of the new enumeration values are different from the previously used string values:
|
|||
public interface IModelMyOptions {
|
If you now recompile the application with the updated module and redistribute it, existing users will not be able to use the application. At the application start, a message will be displayed stating that an error has occurred while loading the Application Model differences. To avoid this, an XML converter should be implemented in the module. The following code snippet illustrates a possible solution:
|
|||
using DevExpress.ExpressApp.Model; |
The converter checks whether the currently processed node is the Options node. If it is, the converter checks whether the OperatingMode property has a legacy value. Then, the "Complex" value becomes OperatingMode.Advanced and all other values become OperatingMode.Basic.
Now, consider another very common scenario when a node's property is renamed. Suppose, a Mode property declared in the Options node was renamed to OperatingMode. The following code snippet illustrates a possible XML converter:
|
|||
using DevExpress.ExpressApp.Model; |
As illustrated by the examples, an XML converter works with one node at a time. So, complex conversions, affecting several nodes at once, are not possible. In these cases, special updaters implementing the IModelNodeUpdater<T> interface should be used.
Implement a Node Updater
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 two parameters. The first parameter is the Application Model node in process, represented by an object implementing the IModelNode interface. The second parameter is the application's Application Model, represented by an object, implementing the IModelApplication interface. Since you have access to the whole Application Model, complex conversions affecting multiple nodes can be performed. Consider the following example.
Suppose your application uses a module which adds an OperatingMode string property to the Application Model's Options node. Originally, the interface extending the Application Model looks like this:
|
|||
public interface IModelMyOptions {
|
Then, the module is updated to a new version which moves the property to a newly introduced child node:
|
|||
using DevExpress.ExpressApp.Model;
public interface IModelMyOptions {
|
If you now recompile the application with the updated module and redistribute it, the original OperatingMode property values specified by users of the application will be lost. To avoid this, a node updater should be implemented. A possible place for the implementation is the updated module:
|
|||
using DevExpress.ExpressApp.Model; |
The updater in the example checks whether the currently processed node has a legacy OperatingMode property value. If there is such a value, it is assigned to the new OperatingMode property, and the legacy property value is cleared.
Note that since a node updater can be implemented anywhere in the application, the updater should be registered via the ModuleBase.AddModelNodeUpdaters method:
|
|||
using DevExpress.ExpressApp.Model; |
Convert Application Model Differences的更多相关文章
- Core - Provide an easy way to store administrator and user model differences in a custom store (e.g., in a database)
https://www.devexpress.com/Support/Center/Question/Details/S32444/core-provide-an-easy-way-to-store- ...
- Implement Property Value Validation in the Application Model 在应用程序模型中实现属性值验证
In this lesson, you will learn how to check whether or not a property value satisfies a particular r ...
- How to map Actions to a certain RibbonPage and RibbonGroup using the Application Model or in code
https://www.devexpress.com/Support/Center/Question/Details/S134617/how-to-map-actions-to-a-certain-r ...
- Windows Forms Application Creation and Initialization
Windows Forms Application Creation and Initialization This topic details the steps performed after a ...
- ASP.NET Application Life Cycle
The table in this topic details the steps performed while an XAF ASP.NET application is running. Not ...
- Unit Testing a zend-mvc application
Unit Testing a zend-mvc application A solid unit test suite is essential for ongoing development in ...
- 【转载】Using the Web Service Callbacks in the .NET Application
来源 This article describes a .NET Application model driven by the Web Services using the Virtual Web ...
- TensorFlow Lite demo——就是为嵌入式设备而存在的,底层调用NDK神经网络API,注意其使用的tf model需要转换下,同时提供java和C++ API,无法使用tflite的见后
Introduction to TensorFlow Lite TensorFlow Lite is TensorFlow’s lightweight solution for mobile and ...
- [AngularJS] 5 simple ways to speed up your AngularJS application
Nowdays, Single page apps are becoming increasingly popular among the fornt-end developers. It is th ...
随机推荐
- 剑指offer 08跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). java版本: public class Solution { public s ...
- 线性规划 Matlab
线性规划的 Matlab 解法 形式 s.t.( subject to) c和 x为n 维列向量, A. Aeq 为适当维数的矩阵,b .beq为适当维数的列向 量. 函数: linprog(c,A, ...
- 一、Linux概述 二、Linux的安装 三、Linux的常用命令(重点)
一.Linux概述###<1>操作系统 OS,管理和控制 计算机的 硬件和软件资源的 计算机程序. 最基本的系统软件. 是用户和计算机交互的桥梁,是硬件和软件交互的桥梁. 操作系统:she ...
- QT 登录记住密码方法之一:Qt QSettings读写配置文件
不过本文写的是明文保存,最好还是加密一下,以防文件被非法读取 /**登录初始化的时候处理这部分操作*/ Settings cfg("user.ini",QSettings::Ini ...
- [T-ARA][Goodbye, OK]
歌词来源:http://music.163.com/#/song?id=22704437 作曲 : 안영민 , 이유진 [作曲 : a-nyeong-min , i-yu-jin] 作词 : 안영민 ...
- ubuntu 12.04 64位 安装wps
1.去wps官网下载linux版的软件 http://community.wps.cn/download/ 我这里下载的是Alpha版的kingsoft-office_9.1.0.4280~a12p4 ...
- 我对git的快速使用和理解
收藏较好的,分享给大家 https://mp.weixin.qq.com/s/k4tU8snvssyKJ2WkvkFrZA
- Python3中内置类型bytes和str用法及byte和string之间各种编码转换
Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str ...
- AOP的本质
AOP的本质是HOOK: HOOK的本质是:新函数包含原函数或新函数替换原函数: 需要解决的问题: 1.新函数的生成: 2.新函数的调用机制: 3.原函数的调用机制: 新函数的生成: 1.将已有的动态 ...
- Hive学习之路 (九)Hive的内置函数
数学函数 Return Type Name (Signature) Description DOUBLE round(DOUBLE a) Returns the rounded BIGINT valu ...