Optimizely CMS 12 and .NET 10 Upgrade: Resolving a TinyMCE Dependency Injection Exception

Framework upgrades often expose hidden compatibility issues that have remained dormant for years. While upgrading one of our Optimizely CMS solutions to .NET 10, we encountered a runtime exception that initially appeared to be a dependency injection problem but ultimately turned out to be an outdated TinyMCE package.

This post documents the issue, the investigation journey, and the surprisingly simple fix.

The Problem

After upgrading our solution to:

  • .NET 10
  • Optimizely CMS 12.34.4

the application failed during startup with the following exception:

AggregateException: One or more errors occurred.
 
Unable to resolve service for type
‘EPiServer.ServiceLocation.ServiceAccessor<EPiServer.Cms.TinyMce.Core.TinyMceConfiguration>’
while attempting to activate
‘DXP.Core.Model.TimelineBlockXhtmlStringEditorDescriptor’.

 

The exception pointed to our custom TinyMCE editor descriptor:

[EditorDescriptorRegistration(
TargetType = typeof(XhtmlString),
EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault,
UIHint = UIHint)]
public class TimelineBlockXhtmlStringEditorDescriptor
: XhtmlStringEditorDescriptor
{
public const string UIHint =
"TimelineBlockXhtmlStringEditorDescriptor";
 
public TimelineBlockXhtmlStringEditorDescriptor(
ServiceAccessor<TinyMceConfiguration> tinyMceConfiguration)
: base(tinyMceConfiguration)
{
}
public override void ModifyMetadata(
ExtendedMetadata metadata,
IEnumerable<Attribute> attributes)
{
// custom implementation
}
}

At first glance, it looked like a service registration or dependency injection issue.

Environment Details

The key package versions at the time were:

  • Optimizely CMS 12.34.4
  • EPiServer.CMS.TinyMce 4.8.3
  • .NET 10

The application had been working correctly before the framework upgrade, which made the issue particularly challenging to diagnose.

Initial Investigation

Our TinyMCE registration was straightforward:

services
.AddCmsAspNetIdentity<ApplicationUser>()
.AddCms()
.AddTinyMce();

and custom configuration was registered using:

services.Configure<TinyMceConfiguration>(config =>
{
// custom TinyMCE settings
});

Everything appeared to be configured correctly.

Testing on Alloy

To isolate the problem, we reproduced similar TinyMCE configuration in a clean Alloy solution running on .NET 10.

The result:

  • CMS started successfully

  • TinyMCE loaded correctly

  • No dependency injection errors

This immediately suggested the problem was not a generic Optimizely or .NET 10 issue.

Reviewing Custom Editor Descriptors

Since the exception referenced:

TimelineBlockXhtmlStringEditorDescriptor

we spent considerable time reviewing:

  • Editor descriptor registrations
  • Dependency injection registrations
  • Startup ordering
  • TinyMCE configuration extensions

Everything looked valid.

Checking Service Registration Order

We also reviewed whether .NET 10 had introduced behavioural differences in service registration and startup initialization.

Multiple registration orders were tested:

services.AddCms();
services.AddTinyMce();
services.Configure<TinyMceConfiguration>();

and

services.Configure<TinyMceConfiguration>();
services.AddCms();
services.AddTinyMce();

No change.

The Root Cause

After eliminating configuration and dependency injection possibilities, attention shifted to package compatibility.

EPiServer.CMS.TinyMce 4.8.3

Although the package had worked successfully before the upgrade, it was clearly not behaving correctly in the .NET 10 environment.

The Fix

We upgraded TinyMCE from:

EPiServer.CMS.TinyMce 5.0.3

After upgrading:

  • Application started successfully
  • TinyMCE initialized correctly
  • Dependency injection exception disappeared
  • Custom editor descriptors continued to work
  • CMS editor experience was fully restored

Happy Optimizely!

Leave a Reply

Your email address will not be published. Required fields are marked *