---
title: Initializing modules to run custom code
related:
  - https://docs.kentico.com/k9/custom-development/creating-custom-modules.md
  - https://docs.kentico.com/k9/custom-development/handling-global-events.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

If you need your [custom module](https://docs.kentico.com/k9/custom-development/creating-custom-modules.md) to modify the behavior of the Kentico application, you can register the module and execute code during its initialization. This approach is recommended when developing customizations directly related to the module (instead of initializing code using the _CMSModuleLoader_ class in _App\_Code)._

1. Open your project in Visual Studio (using the **WebSite.sln** or **WebApp.sln** file).
2. Create a class in the module's code folder, for example _\~/App\_Code/CMSModules/CompanyOverview_.

   > **Info:** If your module uses a separate assembly, add the module class into the corresponding project.
   >
   > Keep in mind that the code of your custom assembly project must contain the **\[assembly: AssemblyDiscoverable]** attribute (the recommended location is in the _Properties/AssemblyInfo.cs_ file). To use the attribute, your assembly's project must contain a reference to the _CMS.Core.dll_ library.
3. Make the module class inherit from **CMS.DataEngine.Module**.
4. Define the constructor of the module class:

   - Inherit from the base constructor
   - Enter the code name of the module as the parameter
   - If you are developing a [module with installation package support](https://docs.kentico.com/k9/custom-development/creating-custom-modules/creating-installation-packages-for-modules.md), you need to set the optional second parameter _(isInstallable)_ to _**true**_
5. Register the module class using the **RegisterModule** assembly attribute.
6. Implement your custom functionality inside the module class.

You can achieve most customizations by running code during the initialization of the module – override the following methods:

- **OnInit (recommended)** - 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, such as working with the data of modules. For example, you can use _OnPreInit_ to register custom implementations of interfaces.

Because you cannot manually set the initialization order of modules or define dependencies between modules, we do not recommend working with the data of other modules directly inside the _OnInit_ method\*.\* The best approach is to [assign handlers to system events](https://docs.kentico.com/k9/custom-development/handling-global-events.md), and perform the actual operations inside the handler methods. For general code that is not related to a specific system event, you can use the **ApplicationEvents.Initialized.Execute** event, which occurs after all modules in the system are initialized.

For example, the following code extends the sample _Company overview_ module from the [Creating custom modules](https://docs.kentico.com/k9/custom-development/creating-custom-modules.md) page. The example uses event handling to log an entry in the system's [Event log](https://docs.kentico.com/k9/developing-websites/troubleshooting-websites/working-with-the-system-event-log.md) whenever a new office is created.

```csharp title="Example"

using CMS;
using CMS.DataEngine;
using CMS.EventLog;

[assembly: RegisterModule(typeof(CompanyOverviewModule))]

public class CompanyOverviewModule : Module
{
    // Module class constructor, inherits from the base constructor with the code name of the module as the parameter
    public CompanyOverviewModule() : base("CompanyOverview")
    {
    }

    /// <summary>
    /// Initializes the module. Called when the application starts.
    /// </summary>
    protected override void OnInit()
    {
        base.OnInit();

        // Assigns a handler to the Insert.After event for OfficeInfo objects
        CompanyOverview.OfficeInfo.TYPEINFO.Events.Insert.After += Office_InsertAfter;
    }

    private void Office_InsertAfter(object sender, ObjectEventArgs e)
    {
        // Logs an information entry into the system's event log whenever a new office is created
        string message = "New office '" + e.Object.GetStringValue("OfficeDisplayName", "") + "' was created in the custom Company overview module.";
        EventLogProvider.LogInformation("Company overview module", "NEW OFFICE", message);
    }
}


```
