Skip to content

Refactor app-layer persistence to typed repositories - #547

Closed
linkdotnet with Copilot wants to merge 2 commits into
masterfrom
copilot/check-idiomatic-repository-implementation
Closed

linkdotnet with Copilot wants to merge 2 commits into
masterfrom
copilot/check-idiomatic-repository-implementation

Conversation

Copilot AI commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

The app layer was coupled directly to IRepository<T>, which breaks down once features span multiple domain objects and relationships. This change moves the web/application layer to feature-oriented repositories while keeping the generic repository as a provider-level primitive for SQL, MongoDB, and RavenDB.

  • Application-facing repository boundaries

    • Introduces typed repositories for the actual feature seams in the app:
      • IBlogPostRepository
      • ISimilarBlogPostRepository
      • IAboutMeRepository
      • IAnalyticsRepository
      • IBrokenLinkRepository
      • IShortCodeRepository
      • IBlogPostTemplateRepository
    • Keeps IRepository<TEntity> as the low-level storage abstraction behind those adapters.
  • Typed adapters over existing providers

    • Adds thin repository adapters that compose the existing generic provider implementations rather than replacing them.
    • Preserves provider parity while moving query shape and orchestration closer to feature boundaries.
  • Blog post caching moved to the typed layer

    • Replaces the special DI override of IRepository<BlogPost> with CachedBlogPostRepository : IBlogPostRepository.
    • Makes caching an explicit application concern instead of a one-off generic repository decoration.
  • Provider health checks decoupled from content repositories

    • Introduces IPersistenceHealthCheck plus SQL / MongoDB / RavenDB implementations.
    • Removes the DatabaseHealthCheck dependency on IRepository<BlogPost>.
  • Web/app consumers migrated off IRepository<T>

    • Updates pages, jobs, controllers, and services to depend on typed repositories instead of raw generic repositories.
    • Covers blog content flows, About Me, analytics, broken links, short codes, and blog post templates.
  • Registration and dummy-data wiring

    • Registers typed repositories in AddStorageProvider.
    • Updates dummy-data setup to remove and re-register the new app-facing abstractions cleanly.
  • Representative shape

    public sealed class BlogPostRepository(IRepository<BlogPost> repository) : IBlogPostRepository
    {
        public ValueTask<BlogPost?> GetByIdAsync(string id) => repository.GetByIdAsync(id);
    
        public ValueTask<IPagedList<BlogPost>> GetAllAsync(
            Expression<Func<BlogPost, bool>>? filter = null,
            Expression<Func<BlogPost, object>>? orderBy = null,
            bool descending = true,
            int page = 1,
            int pageSize = int.MaxValue) =>
            repository.GetAllAsync(filter, orderBy, descending, page, pageSize);
    }

This lays down the application-facing repository structure needed for richer content relationships such as series without pushing more complexity into the generic repository pattern.

Copilot AI and others added 2 commits September 19, 2026 20:21
Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com>
Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com>
@linkdotnet linkdotnet closed this Sep 20, 2026
@linkdotnet
linkdotnet deleted the copilot/check-idiomatic-repository-implementation branch September 20, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants