Model Difference Storages
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.
- Ways to Store Model Differences
- Model Differences Layers
- File Storage
Ways to Store Model Differences
There are four main descendants of the ModelStoreBase class.
- FileModelStore — is used to store Model Differences in a XAFML file.
- ResourcesModelStore — is used to load Model Differences at runtime from resources.
- ModelDifferenceDbStore — is used to store Model Differences in a database.
- CookiesModelDifferenceStore — is used by an ASP.NET application to store user Model Differences in cookies.
By default, an XAF application created with the Solution Wizard uses the following combination of Model Differences storage technologies.
- Customizations of Application projects made using Visual Studio are stored in the FileModelStore.
- Customizations of Module projects made using Visual Studio are stored in the resources and loaded by the ResourcesModelStore.
- Customizations made by an end-user of a WinForms application with the Security System disabled are stored in the FileModelStore.
- Customizations made by an end-user of an ASP.NET application with the Security System disabled are stored in the CookiesModelDifferenceStore.
- Customizations made by an end-user of security-enabled WinForms and ASP.NET applications are stored in the ModelDifferenceDbStore.
Model Differences Layers
The Application Model has a layered structure. Layers are listed below in the order of overlap.
- Integrated Model Differences — UI customizations made in the Module project and stored in application assemblies.
- Administrator's Model Differences — UI customizations made in the Application project and applied to all users by default.
- User's Model Differences — UI customizations that were made by an end-user.
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.
- Model Differences — contains general UI customizations
- Model Difference Aspects — contains localized UI customizations
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.
- IModelDifferenceAspect — to store the XML code of Model Differences in the IModelDifferenceAspect.Xml property
- IModelDifference — to store the collection of ModelDifferenceAspects for each user
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.
- Create Model Differences — creates an empty application model differences for all users in all existing contexts.
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.
- Export Model Differences — saves model differences of the selected user to the <Application folder>\ExportedModelDifferences\<UserName>\Model.User.xafml" file.
- Import Shared Model Difference — loads shared model differences created in Visual Studio (the Model.xafml file) to the Shared Model Difference object.
- Reset Model Differences — clears model differences for the selected user.
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.
Shared Model Differences Management
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.
- SecuredObjectSpaceProvider or XPObjectSpaceProvider created using the constructor with the threadSafe parameter set to true (this parameter enables the ThreadSafeDataLayer).
- Application-wide model differences are stored in the database using the XafApplication.CreateCustomModelDifferenceStore event (you can still store user-specific differences in the database using the XafApplication.CreateCustomUserModelDifferenceStore event).
- Custom Persistent Fields declared in the application-level model differences.
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.