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.
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.
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.
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.
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.
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.