---
title: Initialize CMS 13
slug: cms-13/docs/initialize-cms
docTags: 
createdAt: 2026-07-30T20:22:10.689Z
---

An ASP.NET Core application controls the initialization of the application through the `Startup` class. Optimizely Content Management System (CMS 13) is added to the application by calling the extension method `AddCms()` on `IServiceCollection` (from NuGet package `EPiServer.Cms`). In its registration, that method calls the extension method `AddCmsHost()` on `IServiceCollection` (from NuGet package `EPiServer.Hosting`), which creates the `InitializationEngine` and initializes modules implementing `IInitializableModule`.

`AddCms()` does not automatically register Content Manager. For PaaS (self-hosted) deployments, you must explicitly add this service in your `Startup` or `Program.cs`:

```csharp
services.AddCms();
services.AddContentManager();  // Must be added explicitly for PaaS
```

Custom initialization logic is done through standard ASP.NET Core components like [IStartupFilter](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0\&tabs=visual-studio) or  [IHostedService](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0\&tabs=visual-studio). The `IInitializableModule` system (described below) within CMS that was built for ASP.NET (where there was no central `Startup` class) is also available in the ASP.NET Core application and can also be used.

The Optimizely initialization system comprises the following:

- A discovery mechanism to determine which modules should be part of the initialization process.
- A dependency sorting algorithm that decides the order of execution.
- An execution engine that executes the modules.
- The `EPiServer.Framework.Initialization` namespace, in the `EPiServer.Framework` assembly.

## Discovery mechanism

The scanning of assemblies is primarily using an attribute-based discovery system. CMS uses the [AssemblyLoadContext](https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext) and the `DependencyContext` to locate assemblies to locate which assemblies to scan for initialization modules.

To have a discoverable initialization module, you must add the `[InitializableModule]` or `[ModuleDependency(...)]` attribute to your class. The class must also implement the `IInitializableModule` or `IConfigurableModule` interfaces.

## Dependency sorting

If your application has a dependency on one or more existing initialization modules, explicitly state this dependency by using the `[ModuleDependency(typeof(ModuleThatIDependOn))]` attribute. The dependency sorting uses this to ensure that modules are executed in the correct order. You can define multiple modules on which the application is dependent. For example, in CMS, you can take a dependency on `EPiServer.Web.InitializationModule` to make sure any CMS functionality was initialized before your module.

The modules are then sorted, ensuring that they are executed in the correct dependency order.

If the application defines circular dependencies or dependencies to non-existing modules, you receive an exception upon application startup.

## Execution engine – InitializationEngine

`InitializationEngine` (resides in the namespace `EPiServer.Framework.Initialization`) is responsible for executing the list of modules the dependency sorting algorithm created. The `IInitializableModule.Initialize` method is guaranteed to be called only once (unless an error occurs).

The initialization engine is a simple state machine that logs information about state changes and reports the initialization methods that were executed.

After the `Initialization` methods are executed, an `InitComplete` event is raised, which lets you perform post-initialization actions. See the `InitComplete` event section.

The `InitializationEngine` is created when calling `AddCmsHost()` on `IServiceCollection` (from NuGet package `EPiServer.Hosting`). CMS adds an [IHostedService](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0\&tabs=visual-studio) that, during `StartAsync()`,  calls the initialization engine, which then calls Initialize on detected `IInitializableModule` implementations. This means that `IInitializableModules` are called after the DI configuration of the application is complete but before any HTTP requests are executed.

## Assembly scan and filter

When the initialization system looks for modules, it relies on a common type scanning system based on the standard .NET reflection APIs for loading and composition. The basic idea is to scan assemblies that are part of the application, except for .NET assemblies. This assembly list is exposed through the internal assembly scanner static property. Attribute an assembly with `[PreventAssemblyScan]` to exclude it from the scanning process.

Optimizely products use the same scanning process as the initialization system when discovering plug-ins. This is important to remember when you decide which assemblies are scanned by the EPiServer Framework.

The types that were discovered during scanning are then available through an implementation of lookup `ITypeScannerLookup` component in `EPiServer.Framework.TypeScanner` namespace. Types that define plug-in systems, such as CMS, use an assembly attribute `TypeScannerRegistration` to register plug-in types. Do not use the `TypeScannerRegistration` attribute to register plug-ins; only to register plug-in types. By having a consolidated type scanning system, a single cached sweep over assemblies is required for products to initialize themselves.

## InitComplete event

You can have your initialization module called again after completing the initialization process. A typical use case is to attach event handlers to an instance property that third-party code overrides.

To attach to the `InitComplete` event, write your `Initialize()` method as follows:

```csharp
public void Initialize(InitializationEngine context) {
  context.InitComplete += InitCompleteHandler;
  StartThisModule();
}
```

When initialization modules have executed, the `InitComplete` event is raised. The `InitComplete` event is handled in a slightly non-standard way. When an event handler executes without error, the initialization system removes it from the `InitComplete` event. So do not detach from the `InitComplete` event in your `Uninitialize()` method.

This procedure ensures that if an `InitComplete` event handler encounters an error, CMS re-executes the `InitComplete` event on the next request without re-invoking the already executed event handlers.

## Logging

To enable logging from initialization modules, configure logging for the namespace `EPiServer.Framework.Initialization`.
