Repository APIs
Outline
- Read vs. Write: Distinguish between IContentLoader for optimized caching and IContentRepository for full lifecycle CRUD operations
- Taxonomy Control: Use CategoryRepository for hierarchical organization, ensuring writable clones are used for any programmatic updates
- Binary Assets: Manage media via MediaData and the Blob API to separate metadata from physical storage in PaaS environments
- PaaS Efficiency: Prioritize bulk loading methods and proper security scoping to maintain high-performance architectural governance
Optimizely CMS 12 provides a suite of Repository APIs that serve as the technical foundation for programmatic data interaction. These APIs handle hierarchical content, taxonomy (categories), multi-site configurations, and binary assets (media). For enterprise PaaS environments, understanding the distinction between read-only loaders and full-access repositories is critical for maintaining high performance and ensuring architectural governance.
1. Content Repositories: IContentLoader vs. IContentRepository
The core content engine is split into two primary interfaces to optimize the request pipeline. Both handle IContent objects, but their intended technical roles differ.
Read-Only Performance: IContentLoader
IContentLoader is the primary interface for frontend delivery and data retrieval.
-
Caching Participation: Deeply integrated with the Optimizely object cache (
ISynchronizedObjectInstanceCache), meaning repeated reads of the same content do not hit the database. -
Language Handling: Provides robust support for
CultureInfoand fallback mechanisms such asLanguageLoaderOption.FallbackWithMaster(). -
Type Filtering: Automatically filters returned collections to match the requested generic type, preventing
TypeMismatchException.
Full Lifecycle Management: IContentRepository
IContentRepository extends the loader to include full CRUD operations (Create, Update, Delete). Write operations involve database transactions, search indexing triggers, and cache invalidation - use IContentLoader for reads to avoid this overhead.
Note: Content objects returned by the repository are read-only by default. Always call .CreateWritableClone() before modifying any property - attempting to modify a read-only instance throws an EPiServerException at runtime.
2. Taxonomy Management: CategoryRepository
The CategoryRepository manages the site's system-wide taxonomy. Categories are structural nodes used for filtering and organizing large content sets across all page types.
Programmatic Patterns
- Retrieval: Categories can be accessed by ID or Name. Retrieve categories in controllers or services rather than directly in views to keep rendering logic clean.
-
Modifiability: Like content pages, categories returned by the repository are read-only. Modifying a category requires calling
.CreateWritableClone()first. - Parent-Child Updates: When adding a new category, the system does not automatically refresh previously loaded parent collections. The parent must be reloaded to reflect the updated hierarchy.
3. Multi-site Infrastructure: SiteDefinitionRepository
In enterprise PaaS environments, multiple brands or locales often coexist in a single instance. The SiteDefinitionRepository manages the technical boundaries between these sites.
Strategic Site Access
While site definitions are predominantly configured via the CMS Admin UI, developers interact with the repository to resolve context-aware logic:
-
SiteDefinition.Current: The standard shorthand to retrieve the settings (
StartPage,RootPage, hostname) for the current incoming request. -
Multi-site Context: When building background jobs or scheduled tasks that run outside a web request, use the repository to programmatically iterate through all registered sites rather than relying on
SiteDefinition.Current, which will be null in that context.
4. Media and Asset Management: MediaData and the Blob API
Media in CMS 12 is treated as a specialized content type inheriting from MediaData or ImageData. Binary data is not stored in the SQL database - it is offloaded to configured BLOB providers such as Azure Blob Storage.
Programmatic Media Creation
Creating media assets programmatically requires combining content creation with binary persistence using the .SaveBlob() method. The three-step pattern below separates metadata from binary data correctly.
5. Performance and Governance Best Practices for PaaS
High-performance PaaS environments require strict adherence to repository usage standards to ensure scalability.
-
Prefer IContentLoader: Always default to the loader for frontend components. Reserve
IContentRepositoryfor write operations only. -
Bulk Loading: Use
GetItems()when retrieving a collection of references rather than looping with individualGet()calls. Bulk loading enables batched cache lookups and reduces database round trips. -
Security Scoping: Always apply an appropriate
AccessLevelduring repository operations to match the execution context - do not default toAccessLevel.NoAccessin frontend contexts. -
Projections over Content: In search implementations, project results into ViewModels to avoid loading full
IContentobjects unnecessarily - search results often only need a subset of properties.
Pro tip: A common performance bottleneck on content-heavy pages is N+1 loading - a loop that calls Get() inside a foreach. Always collect the references first, then call GetItems() once.
Conclusion
The Repository APIs in Optimizely CMS 12 define the standard contract for interacting with the platform's data. By distinguishing between read-optimized loaders and full-lifecycle repositories, technical teams can build architectures that are both flexible and highly performant. Strategic implementation of CategoryRepository for taxonomy and the Blob API for media ensures that enterprise solutions remain scalable and maintainable across multi-site PaaS deployments.
