ModuleBase Class
The base class for XAF modules.
Namespace: DevExpress.ExpressApp
Assembly: DevExpress.ExpressApp.v24.1.dll
NuGet Package: DevExpress.ExpressApp
Declaration
Remarks
The presence of a ModuleBase
class descendant in a standard Class Library project indicates that this is a module project.
You can use modules to customize the Application Model when it is being loaded.
Collect Types Declared Within the Module: Performance Optimization
XAF uses reflection to collect all types declared in the current module. To optimize type collection in your application, override the following methods:
GetDeclaredExportedTypes()
. Collects business classes available in the assembly and exports them to the Application Model.GetDeclaredControllerTypes()
. Collects Controllers available in the assembly and exports them to the Application Model.GetRegularTypes()
. Collects built-in types required (business objects,DbContext
descendants, Controllers, List and Property Editors, and others).
Note
If you override the GetRegularTypes
method, XAF stops collecting the types declared in the module and you need to register each new Business Object, Controller, or Editor in this method. However, you do not need to register types that are already returned by overridden GetDeclaredExportedTypes
and GetDeclaredControllerTypes
methods.
RegisterEditorDescriptor()
. Use it to disable reflection.
Load Additional Modules
Use the GetRequiredModuleTypesCore
method to add the required modules to the Application Model together with the current module. The current module should have a reference to the modules that you want to add.
Add Custom Nodes and Properties
Override the ModuleBase.ExtendModelInterfaces method to add required nodes or properties. If you need to add a custom node, first declare its interface by inheriting from IModelNode. For more information, see Extend and Customize the Application Model in Code.
Update the Application Model Using the Generator Updaters
Override the ModuleBase.AddGeneratorUpdaters method to add Generator Updaters that update the Application Model.
Add External Business Objects and Controllers to the Application Model
Override the GetDeclaredControllerTypes
and GetDeclaredExportedTypes
methods as displayed in the following code snippet:
namespace MySolution.Module {
public sealed partial class MySolutionModule : ModuleBase {
protected override IEnumerable<Type> GetDeclaredControllerTypes() {
var originalList = (Type[])base.GetDeclaredControllerTypes();
var newList = originalList.ToList();
newList.Add(typeof(ClassLibrary1.CustomController));
return newList;
}
protected override IEnumerable<Type> GetDeclaredExportedTypes() {
var originalList = base.GetDeclaredExportedTypes();
var newList = originalList.ToList();
newList.Add(typeof(ClassLibrary1.MyCustomTask));
return newList;
}
}
}
Update the Database Using Module Updaters
Override the ModuleBase.GetModuleUpdaters method to add ModuleUpdater objects that update the database.
Customize Type Information
Override the ModuleBase.CustomizeTypesInfo method to customize information about a particular class or property before it is loaded to the Application Model. For more information, refer to the following topic: Use Metadata to Customize Business Classes Dynamically.
Register a List or Property Editor
Override the protected RegisterEditorDescriptor
method to disable the reflection mechanism that collects information about types decorated by ListEditorAttribute and PropertyEditorAttribute. This expedites application startup.
Note
In this case, Editors that are decorated by ListEditorAttribute and PropertyEditorAttribute are not registered.
Use EditorDescriptorsFactory.RegisterListEditorAlias and EditorDescriptorsFactory.RegisterListEditor methods to register your List Editor with its alias.
To register a Property Editor, use EditorDescriptorsFactory.RegisterPropertyEditorAlias and EditorDescriptorsFactory.RegisterPropertyEditor methods.
You can associate an EditorAliases enumerator value or a custom alias with a target type. You can register one alias for WinForms, ASP.NET Web Forms, and ASP.NET Core Blazor Editors in the base module project and locate corresponding Editors in platform-dependent projects. If you use platform-agnostic Editors for certain types, specify a special string alias to use them in a platform-independent module.
Note
The Editor registered for the Object
type serves as a fallback/default editor for objects and properties not associated with a specific Editor type.
The following example demonstrates how to register a default List Editor:
public class MyModule : ModuleBase {
//...
protected override void RegisterEditorDescriptors(EditorDescriptorsFactory
editorDescriptorsFactory) {
editorDescriptorsFactory.RegisterListEditorAlias("CustomListEditorAlias",
typeof(object), true);
editorDescriptorsFactory.RegisterListEditor("CustomListEditorAlias",
typeof(object), typeof(GridListEditor), true);
}
}
The list below describes how to customize this example.
- Pass type
Object
as theelementType
parameter andfalse
as theisDefaultEditor
parameter. The method add the Editor to the IModelViews.DefaultListEditor list. This enables this Editor in the Model Editor. - To register the default List Editor for objects of a specific type, pass the target type to the methods’
elementType
parameter and set theisDefaultEditor
parameter totrue
to mark this Editor as the default editor for this type. - Pass a type as the
elementType
parameter andfalse
as theisDefaultEditor
parameter. The method adds the List Editor to the IModelClass.EditorType list for the specified type. This allows you to choose this Editor in the Model Editor. Use the
classHandler
parameter of theRegisterListEditorAlias
method if you want to register a number of Editors for one type and choose an editor according to custom logic. The editor that matches the specified conditions is applied to the current type first.public class MyModule : ModuleBase { //... protected override void RegisterEditorDescriptors(EditorDescriptorsFactory editorDescriptorsFactory) { //... editorDescriptorsFactory.RegisterListEditorAlias("MyAlias", typeof(object), IsCriteriaProperty); } private static bool IsCriteriaProperty(IModelClass modelClass) { //... } }
The following example demonstrates how to register a default Property Editor:
public class MyModule : ModuleBase {
//...
protected override void RegisterEditorDescriptors(EditorDescriptorsFactory
editorDescriptorsFactory) {
//...
editorDescriptorsFactory.RegisterPropertyEditorAlias("CustomPropertyEditorAlias",
typeof(object), true);
editorDescriptorsFactory.RegisterPropertyEditor("CustomPropertyEditorAlias",
typeof(object), typeof(DefaultPropertyEditor), true);
}
}
Note
To set a Property Editor as default for properties with protected content, implement the IProtectedContentEditor
interface in the Property Editor.
The list below describes how you can modify this example.
- Pass type
Object
as theelementType
parameter andfalse
as theisDefaultEditor
parameter. The method adds the Editor to the IModelRegisteredViewItem.DefaultItemType list of default Property Editors or the IModelRegisteredPropertyEditors.ProtectedContentPropertyEditor list if your Editor is for the properties with protected content. This allows you to choose this Editor in the Model Editor. - To register the default Property Editor for the properties of a specific type, pass the target type to the methods’
elementType
parameter and set theisDefaultEditor
parameter tofalse
to mark this Editor as the default editor for this type. - Specify the target type in the methods’
elementType
parameter and set theisDefaultEditor
parameter tofalse
to add the Property Editor to the IModelRegisteredPropertyEditor.EditorType list of Property Editors for the specified type. Then, you can choose this Editor in the Model Editor. Use the
memberHandler
parameter of theRegisterPropertyEditorAlias
method if you want to register a number of Editors for properties of one type and choose the appropriate Editor according to the logic implemented in it. In different situations, the Editor satisfying the conditions is applied to current type first. Editors registered with this parameter have priority over Editors registered without it. For the Editor registered with thememberHandler
parameter, the new node is created in the Model Editor’s View Items | PropertyEditors node.public class MyModule : ModuleBase { //... protected override void RegisterEditorDescriptors(EditorDescriptorsFactory editorDescriptorsFactory) { //... editorDescriptorsFactory.RegisterPropertyEditorAlias("MyAlias", typeof(DateTime), IsMemberCompatibleHandler); } private static bool IsMemberCompatibleHandler(IModelMember modelMember) { //... } }
You do not have to create instances of ModuleBase
class descendants. They are created automatically.
To add a module to your application, use the Module Designer or Application Designer.
Add External Business Objects and Controllers to the Application Model
XAF uses reflection to collect classes and Controllers from each module and build an Application Model. Use the following techniques to customize this process:
Use the ModuleBase.AdditionalControllerTypes and ModuleBase.AdditionalExportedTypes properties to specify business classes and Controllers that should be loaded to the Application Model:
File: MySolution.Module/Module.cs(.vb)
namespace MySolution.Module { public sealed partial class MySolutionModule : ModuleBase { public MySolutionModule() { InitializeComponent(); AdditionalControllerTypes.Add(typeof(ClassLibrary1.Controller1)); AdditionalExportedTypes.Add(typeof(ClassLibrary1.PersistentClass1)); } // ... } }
In .NET Framework applications, you can open the Module Designer and modify the Controllers and Exported types sections.
.
Override the
GetDeclaredControllerTypes
andGetDeclaredExportedTypes
methods of theModuleBase
class to add external business objects and Controllers to the Application Model:File: MySolution.Module/Module.cs(.vb)
namespace MySolution.Module { public sealed partial class MySolutionModule : ModuleBase { protected override IEnumerable<Type> GetDeclaredControllerTypes() { var originalList = (Type[])base.GetDeclaredControllerTypes(); var newList = originalList.ToList(); newList.Add(typeof(ClassLibrary1.CustomController)); return newList; } protected override IEnumerable<Type> GetDeclaredExportedTypes() { var originalList = base.GetDeclaredExportedTypes(); var newList = originalList.ToList(); newList.Add(typeof(ClassLibrary1.MyCustomTask)); return newList; } } }
Replace Data Model Classes in a Built-In Module
If you want to use a custom entity type in a built-in module, configure this type in the Application Builder’s module settings. For more information on how to do this, refer to the following topic: Register Extra Modules in the Application Builder.