Run code on application startup
Xperience customization scenarios sometimes require you to call specific system API during application startup to achieve the desired behavior. Some examples include:
- assigning handlers to global system events
- adding custom implementations of objects to global collections (e.g., personal data erasers and collectors)
- registering custom JavaScript modules containing admin UI customizations
The system provides a convenient entry point for such code in the form of code-only modules. Modules are custom classes that provide the following methods:
OnInit
– the system executes the code during the initialization (start) of the application. A typical example ofOnInit
code is assigning handler methods to system events.OnPreInit
– the system executes the code beforeOnInit
. Does not support any operations that require access to the database. For example, can be used to register custom data types.
Xperience collects all module classes during application startup and executes their OnInit
and OnPreInit
methods. The initialization order of modules is not guaranteed and cannot be controlled (modules can be initialized in a different order every time the application starts). For this reason, we don’t recommend relying on the initialization order in your custom code.
Run custom code on application startup
To run custom code on application startup:
Open your Xperience project in Visual Studio.
Create a custom class that inherits from
CMS.DataEngine.Module
.- See Integrate custom code for best practices about adding custom classes to Xperience projects.
Define the constructor of the module class:
- Inherit from the base constructor.
- Enter the code name of the module as the base constructor parameter. The code name must be unique within the application.
Register the module class using the
RegisterModule
assembly attribute.Override the
OnInit
orOnPreInit
method (follow the guidelines of your particular customization scenario) and call the required startup code inside.Override
OnInit(ModuleInitParameters)
to access the application’s service container via IServiceProvider, for example if you need to resolve dependencies required for the module’s code.C#protected override void OnInit(ModuleInitParameters parameters) { // Resolve services via IServiceProvider. e.g., IEventLogService parameters.Services.GetRequiredService<IEventLogService>(); ... }
Override
OnPreInit(ModuleInitParameters)
if you wish to access the application’s IServiceCollection during module pre-initialization. For example, you can dynamically configure the application’s startup options.C#protected override void OnPreInit(ModulePreInitParameters parameters) { // Access IServiceCollection, e.g., to configure startup options like EmailQueueOptions parameters.Services.Configure<EmailQueueOptions>(...); ... }
The system executes the methods when collecting registered modules during application startup.
Example
The following example resolves dependencies on other services from IServiceProvider
accessed via ModuleInitParameters
.
using CMS;
using CMS.Core;
using CMS.DataEngine;
using CMS.Membership;
using Microsoft.Extensions.DependencyInjection;
[assembly: RegisterModule(typeof(CustomModule))]
public class CustomModule : Module
{
private IEventLogService eventLogService;
// Module class constructor, inherits from the base constructor with the code name of the module as the parameter
public CustomModule() : base(nameof(CustomModule))
{
}
protected override void OnInit(ModuleInitParameters parameters)
{
// Access 'IServiceProvider' via ModuleInitParameters and resolve 'IEventLogService'
eventLogService = parameters.Services.GetRequiredService<IEventLogService>();
// Registers an event handler
UserInfo.TYPEINFO.Events.Insert.After += User_InsertAfter;
}
private void User_InsertAfter(object sender, ObjectEventArgs e)
{
// Logs an information entry into the system's event log whenever a new user is created
string message = "New user '" + e.Object.GetStringValue("UserName", "") +
"' was created.";
eventLogService.LogInformation(source: "User registration",
eventCode: "NEW USER",
eventDescription: message);
}
}