Changes to the Category API in CMS 8
This topic describes improvements to the performance of categories in Optimizely Content Management System (CMS 8), by updating the Category API to use the read-only instance pattern commonly used in other areas of the API.
To improve the performance of categories in Optimizely Content Management System (CMS 8), the Category API was updated to use the read-only instance pattern commonly used in other areas of the API. This means that requested categories are returned as read-only instances by default, and modification can be done only after a writable clone has been requested. As a part of the change, a new CategoryRepository
class is introduced to improve the testability of the API. This repository replaces the now-obsolete methods directly on the Category
class, such as GetRoot()
and Save
.
Example of modifying a Category
:
var categoryRepository = ServiceLocator.Current.GetInstance<CategoryRepository>();
var myCategory = categoryRepository.Get("MyCategory"); // Returns a read-only instance
myCategory = myCategory.CreateWritableClone();
myCategory.Description = "My category is really nice";
categoryRepository.Save(myCategory);
Changes to the parent collection
Another smaller change is that the parent Category
instance is no longer modified beyond the current when adding or deleting a category. This means you must reload the parent category to get an updated version with/without the added/deleted category. For example:
var parent = categoryRepository.Get("Parent");
var childCategory = new Category(parent, "Child");
categoryRepository.Save(childCategory);
// parent.Categories will not contain a "Child" category here.
parent = categoryRepository.Get("ParentCategory");
// parent.Categories will now contain the "Child" category
Support for moving categories
The Save
method now respects changes to the Parent
property. So, it's possible to move a category from one parent to another without having to recreate it. This also means that content items associated with the moved category maintain their association after the move.
Changes to CategoryCollection
To make the category tree easier to use, we changed the CategoryCollection
class to no longer inherit from CollectionBase
. Now, it implements IList<Category>
instead of just IList.
Full list of breaking Category API changes
While we tried to keep the API as backward-compatible as possible, some behavioral changes were introduced with version 8. The following changes made to the API are considered breaking:
Category
now implementsIReadOnly
.Save()
requires that the category is writable when called.Category.GetRoot()
now returns a read-onlyCategory
instance.Category.Delete()
no longer removes itself from its parent's categories.Category.Delete()
no longer clears theCategories
property when called.Category.Save()
with a new category no longer adds itself to its parent's categories.Category.Save()
with new category now respects the sort order if given.Category.Save()
now requires the name to be unique among siblings.Category.Save()
now respects a change of parents.Category.Save()
now throwsArgumentException
instead ofDataAbstractionException
when theCategory
is in an invalid state.Category.GetList()
implementation has changed to returns a list of typeList<Category>
instead of aCategoryCollection
.CategoryCollection
no longer inherits fromCollectionBase
, it now implementsIList<Category>
.CategoryCollection
now implementsIReadOnly
.CategoryCollection.AddRange()
now validates and sets theParent
property of the insertedCategories
the same way asAdd()
does.CategoryCollection
now throwsInvalidOperationException
instead ofDataAbstractionException
if theParent
value of the insertedCategory
doesn't match.CategoryList.MemberOfAny()
overloads were combined into one.CategoryList.MemberOfAll()
overloads were combined into one.CategoryList.GetHashCode()
now returns the same hash for two instances that match according to theEquals()
method.
Note that many parts of the old API were marked obsolete. These items have compile-time information describing the change and where to find the equivalent method in the updated API.
Updated 8 months ago