Split the ITopicRepository contract so there's a read-only version of it. Today, ITopicRepository is one large interface covering everything: reading content, reading configuration and version history, and writing content (via Save(), Move(), and Delete()). This carves out the reading content into a new, smaller IReadOnlyTopicRepository, then makes the full ITopicRepository inherit from it.
Crucially, this plan ships the contract only: No new read-only repositories are actually built. Every existing repository automatically satisfies the new interface because they already implement ITopicRepository. The organizing principle for what goes where is deliberately narrow: IReadOnlyTopicRepository means read access to the live content graph, while configuration reads (GetContentTypeDescriptors()), version-history reads, and all mutation stay on ITopicRepository.
This is a breaking change for theoretical external adopters, so it will be shipped the 6.0.0 release.
Note: The motivation is library "hygiene", not an immediate first-party need; it follows the same precedent as .NET's own IReadOnlyList<T>. A downstream implementer could implement just the read surface without being forced to include write methods that throw a NotImplementedException. For instance, this might be used for a read-only replica serving a public-facing site whose editor runs on a separate host.
Tasks
Split the
ITopicRepositorycontract so there's a read-only version of it. Today,ITopicRepositoryis one large interface covering everything: reading content, reading configuration and version history, and writing content (viaSave(),Move(), andDelete()). This carves out the reading content into a new, smallerIReadOnlyTopicRepository, then makes the fullITopicRepositoryinherit from it.Crucially, this plan ships the contract only: No new read-only repositories are actually built. Every existing repository automatically satisfies the new interface because they already implement
ITopicRepository. The organizing principle for what goes where is deliberately narrow:IReadOnlyTopicRepositorymeans read access to the live content graph, while configuration reads (GetContentTypeDescriptors()), version-history reads, and all mutation stay onITopicRepository.This is a breaking change for theoretical external adopters, so it will be shipped the 6.0.0 release.
Tasks
IReadOnlyTopicRepositoryand reparentITopicRepositoryOnTopic/Repositories/IReadOnlyTopicRepository.csITopicRepositoryonto the new interface:TopicLoadedeventLoad()default interface method (=> Load(-1))Load(int topicId, Topic? referenceTopic, bool isRecursive, TopicPayload payload)Load(string uniqueKey, Topic? referenceTopic, bool isRecursive, TopicPayload payload)Refresh(Topic referenceTopic, DateTime since)public interface ITopicRepository : IReadOnlyTopicRepository<summary>/<remarks>explicitly noting thatGetContentTypeDescriptors()and the version-Loadoverloads intentionally stay onITopicRepository(they're for configuration and editing, not normal content reads)crefs broken by the move (i.e., allCS1574warningsTopicLoaded's own summary<inheritdoc>comments inObservableTopicRepository.cs)IReadOnlyTopicRepositoryOnTopic/Mapping/TopicMappingService: Constructor parameter and_topicRepositoryfieldOnTopic/Mapping/Hierarchical/HierarchicalTopicMappingService<T>: Constructor parameter andTopicRepositorypropertyIReadOnlyTopicRepositorywhere only reads are exercised