Refactoring Patterns
Outline
- Foundation first: Target .NET 10 and unify NuGet packages before touching business logic.
- Identity gate: Prioritize Opti ID and service registration to ensure administrative access.
- Type evolution: Systematically replace legacy singletons and types like PageReference with modern equivalents.
- Feature timing: Defer complex search and UI refactors until the core application model is stable.
Modernizing an application from Optimizely CMS 12 to CMS 13 requires a phased refactoring strategy. While the migration is fundamentally more straightforward than previous major version jumps, the service-bound nature of the new architecture dictates a specific order of operations. Technical teams must prioritize infrastructure and identity to establish a working environment before tackling feature-level refactoring and legacy code retirement.
1. Phase 1: Critical Infrastructure and Gating Updates
Refactoring must begin at the project definition level. Attempting to address business logic or UI extensions before updating the underlying runtime will result in widespread compilation errors and dependency conflicts.
1.1 .NET 10 Runtime Targeting
The initial refactor target is the TargetFramework within all .csproj files. This is the mandatory foundation for all subsequent package updates.
1.2. NuGet Package Unification
Following the framework update, all Optimizely dependencies must transition to the 13.x release series. This includes core packages and the mandatory identity decoupling package.
-
Core CMS:
EPiServer.CMSandEPiServer.CMS.UI.Core -
Identity: Decouple local identity by adding
EPiServer.Cms.UI.OptimizelyIdentity -
Infrastructure: Ensure
Microsoft.EntityFrameworkCorereferences match the .NET 10 runtime requirements (version 10.0.x).
2. Phase 2: Startup Logic and Identity Orchestration
Once the infrastructure is compile-ready, the service registration pipeline within Program.cs or Startup.cs requires refactoring to accommodate the new platform identity model.
Centralized Identity Registration
Identity management refactoring is a high-priority step because it gates access to the administrative interface. The move to Opti ID necessitates the removal of legacy virtual role providers and the adoption of the AddOptimizelyIdentity extension.
3. Phase 3: Application Model and Reference Refactoring
After the application is operational and accessible via Opti ID, the focus shifts to internal architectural cleanup. These updates can be handled later in the cycle but must be completed before the solution is considered stable.
Application Resolver Implementation
Replacing SiteDefinition.Current usage is a material refactor. The legacy singleton pattern is retired in favor of the asynchronous IApplicationResolver.
-
Update First: Remove all static references to
SiteDefinition.Current. -
Update Later/In Parallel: Refactor services to inject
IApplicationResolverand migrate hostname mappings to the new Application model.
Type Unification (PageReference to ContentReference)
A pervasive refactor involves the removal of the PageReference type.
-
Strategy: Systematically replace all instances of
PageReferencewithContentReference. -
Property Mapping: Update class definitions where
PageLinkwas used, mapping them to the more genericContentLinkproperty.
4. Phase 4: Feature-Level Migrations (Search and UI)
The final phase involves transitioning complex feature sets that have been decommissioned or replaced. Due to the refactoring effort involved, these are often planned for the latter half of the upgrade cycle.
-
Search and Navigation Decommissioning: Transitions from legacy
SearchClientlogic to Optimizely Graph should occur after content synchronization is verified. This ensures search template refactors have a reliable GraphQL data source. -
UI Shell Tag Helpers: Custom administrative layouts must be refactored to utilize the
<platform-navigation />tag helper to ensure alignment with the new identity bar.
Conclusion
Successful refactoring for CMS 13 is governed by dependency priority. By addressing the .NET 10 runtime and identity gates immediately, technical teams establish a stable sandbox for the later work of API cleanup and search refactoring. This prioritized approach ensures that critical system failures are identified early in the upgrade cycle, allowing for a focused transition toward the fully integrated Optimizely One ecosystem.
