Skip to content

IReadOnlyTopicCollection #143

Description

@JeremyCaney

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

  • Introduce IReadOnlyTopicRepository and reparent ITopicRepository
    • Create OnTopic/Repositories/IReadOnlyTopicRepository.cs
    • Move the live-content read members (verbatim, with their XML docs) off ITopicRepository onto the new interface:
      • TopicLoaded event
      • Load() 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)
    • Reparent the interface: public interface ITopicRepository : IReadOnlyTopicRepository
    • Add a paragraph to the new interface's <summary>/<remarks> explicitly noting that GetContentTypeDescriptors() and the version-Load overloads intentionally stay on ITopicRepository (they're for configuration and editing, not normal content reads)
    • Fix crefs broken by the move (i.e., all CS1574 warnings
      • TopicLoaded's own summary
      • <inheritdoc> comments in ObservableTopicRepository.cs)
  • Narrow the two forward-mapping consumers to depend only on IReadOnlyTopicRepository
    • OnTopic/Mapping/TopicMappingService: Constructor parameter and _topicRepository field
    • OnTopic/Mapping/Hierarchical/HierarchicalTopicMappingService<T>: Constructor parameter and TopicRepository property
    • Retype any affected unit-test stubs to IReadOnlyTopicRepository where only reads are exercised

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions