UI customizations made using the Model Editor are called Model Differences and can be stored in different ways. XAF has a ModelStoreBase class, whose descendants define the method for storing Model Differences.
There are four main descendants of the ModelStoreBase class.
By default, an XAF application created with the Solution Wizard uses the following combination of Model Differences storage technologies.
The Application Model has a layered structure. Layers are listed below in the order of overlap.
If the same parameter's value is different in two or more layers, the actual value will be taken from the layer with a higher number. To learn more about the Application Model's Layered Structure, refer to the Application Model Basics topic.
You can assign a different storage type for Administrator and User Model Differences. Subscribe to the XafApplication.CreateCustomUserModelDifferenceStore event to change the User Model Differences storage type and to the XafApplication.CreateCustomModelDifferenceStore to change the Administrator's Model Differences storage type. The default storage types are listed in the table below.
|Layer||Default storage Type for the WinForms applications||Default storage Type for the ASP.NET applications||Default storage Type for the Mobile applications|
|Integrated Model Differences||Assembly resources||Assembly resources||Assembly resources|
|Administrator Model Differences||FileModelStore||FileModelStore||FileModelStore|
|User Model Differences (No Security System)||FileModelStore||CookiesModelDifferenceStore||not supported|
|User Model Differences (Security System Enabled)||ModelDifferenceDbStore||ModelDifferenceDbStore||not supported|
To store Model Differences in files, XAF uses *.xafml files that can be edited by the Model Editor. There are two types of *.xafml files.
The table below shows the name and the location of different *.xafml files.
|Layer||Model Differences||Model Difference Aspects||Location|
|Integrated Model Differences||Model.DesignedDiffs.xafml||Model.DesignedDiffs.Localization.<language code>.xafml||Assembly resources|
|Administrator Model Differences||Model.xafml||Model.<language code>.xafml||Application folder|
|User Model Differences||Model.User.xafml||Model.User.<language code>.xafml||Application folder or the %USERPROFILE%\AppData folder .|
The User Model Differences location is specified in the App.config file, using the UserModelDiffsLocation key in the appSettings section.
<appSettings> <!-- ... --> <add key="UserModelDiffsLocation" value="CurrentUserApplicationDataFolder"/> <!-- ... --> </appSettings>
Possible values are:
|None||User differences are not saved.|
|ApplicationFolder||User differences are stored in the application working folder (together with the application executable).|
|CurrentUserApplicationDataFolder||User differences are stored in the user profile (the %USERPROFILE%\AppData folder).|
The default is ApplicationFolder.
Refer to the How to: Store the Application Model Differences in the Database topic to learn how to enable the Database Storage in an existing application.
To store Model Differences in the database, XAF uses persistent classes that implement in the following interfaces.
Objects implementing these two interfaces are related to each other as one to many (one Model Differences set has many Model Difference Aspects).
Each Model Difference is assigned to a certain user using the IModelDifference.UserId property. Empty UserId means that the current Model Difference is shared by all users and is superimposed with their individual Model Differences. Each user can have various Model Differences in different contexts (e.g., one for a WinForms and another for an ASP.NET application). The context is specified using the IModelDifference.ContextId property.
Objects implementing the IModelDifferenceAspect interface also store application localizations. The aspect applied to all languages by default has an empty string in the IModelDifferenceAspect.Name property.
If you use the Integrated security mode or the Middle Tier server, ensure that all users have read/write access to ModelDifference and ModelDifferenceAspect types (users with read-only permissions cannot persist application customizations when exiting). Read and write permissions are required for the Model.xafml file import operation. In the Middle Tier scenario, the Create permission is additionally required.
As an alternative for giving a user read-only permissions, you can use the WinApplication.IgnoreUserModelDiffs property to ignore the User's Model Differences.
To easily manage Model Differences stored in the database, you can add an extra navigation item as described in the How to: Enable the Administrative UI for managing Users' Model Differences article.
Administrative UI includes the following Actions located in the Tools category.
Copy Model Difference — opens a dialog to copy model differences for the selected user to another user. In this dialog, you can choose either to Overwrite target model differences, or Merge the source and the target using the Copy Behavior option.
The IModelDifference's property UserId defines the owner of the Model Differences set. There is a user-friendly non-persistent IModelDifference.UserName property that contains the name of the Model Differences set owner. Administrator's Model Differences are stored in the object with an empty string in the IModelDifference.UserId property and named "Shared Model Difference". This text is loaded from the localizable value in the Application Model located at Localization | Texts | SharedModelDifferenceName.
User's Model Differences are saved when a user logs off, but the Administrator can change users' model differences while they are still logged into the application. In this case, application model customizations made by the Administrator will be lost. To handle such a situation, the IModelDifference.Version property was added. It is incremented every time the application model is changed by the Administrator, and if the IModelDifference.Version property value at the moment the user logs off is higher than it was at log in (an Administrator makes changes while the user was in the application), the user's changes are not saved and the administrator's changes persist.
The code that enables storing shared model differences (administrator settings) in the database is added by the Solution Wizard to the WinModule.cs (WinModule.vb) and WebModule.cs (WebModule.vb) files, but is commented out. So, the design-time settings are always loaded by default. You can uncomment the XafApplication.CreateCustomModelDifferenceStore event subscription manually, when required. Note that the Model.xafml file content will be loaded to the database once the application is started. Further changes with this file will be ignored if the database record already exists for the shared model differences. To reload settings from Model.xafml, enable the administrative UI and use the Import Shared Model Difference Action (or delete the Shared Model Difference record and restart).
The following combination of features is not supported when used together.
In this configuration, your application loads information on custom persistent fields from the database and then updates the database schema. However, a thread-safe data layer does not support altering the data model after the database connection is established.