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: 

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 of OnInit code is assigning handler methods to system events.
  • OnPreInit – the system executes the code before OnInit. 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:

  1. Open your Xperience project in Visual Studio.

  2. Create a custom class that inherits from CMS.DataEngine.Module.

  3. 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.
  4. Register the module class using the RegisterModule assembly attribute.

  5. Override the OnInit or OnPreInit 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.

C#
Service resolution using 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);
    }
}