Receber por email
← Voltar para o catálogo

dotnet-repository-pattern

Generates Repository interfaces and implementations following the Repository pattern. Provides data access abstraction for aggregate roots with EF Core implementations.

66estrelas
Atualizado há 5 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add ronnythedev/dotnet-clean-architecture-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/dotnet-repository-pattern/svg)](https://www.skillteca.com.br/skills/dotnet-repository-pattern)

Skills relacionadas

Ver todas de Desenvolvimento →

Alerta por categoria

Receba novas skills de Desenvolvimento toda segunda

1 email curto, só com as skills novas de Desenvolvimento. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Repository Pattern Generator

Overview

This skill generates Repositories that provide an abstraction over data access:

  • Interface in Domain layer - Defines data access contract
  • Implementation in Infrastructure - Uses EF Core
  • Per Aggregate Root - Not per entity
  • Unit of Work integration - SaveChanges via IUnitOfWork

Quick Reference

| Repository Method | Purpose | Returns | |-------------------|---------|---------| | GetByIdAsync | Retrieve by primary key | Entity? | | GetByXxxAsync | Retrieve by business key | Entity? | | GetAllAsync | Retrieve all (use sparingly) | IReadOnlyList<Entity> | | Add | Track new entity | void | | Update | Track modified entity | void | | Remove | Track deleted entity | void | | ExistsAsync | Check existence | bool |

Repository Structure

/Domain/{Aggregate}/
└── I{Entity}Repository.cs          # Interface (Domain layer)

/Infrastructure/Repositories/
└── {Entity}Repository.cs           # Implementation (Infrastructure layer)

Template: Repository Interface (Domain Layer)

// src/{name}.domain/{Aggregate}/I{Entity}Repository.cs
namespace {name}.domain.{aggregate};

public interface I{Entity}Repository
{
    // ═══════════════════════════════════════════════════════════════
    // QUERY METHODS
    // ═══════════════════════════════════════════════════════════════
    
    /// <summary>
    /// Gets an entity by its unique identifier
    /// </summary>
    Task<{Entity}?> GetByIdAsync(
        Guid id,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets an entity by its unique identifier with related entities
    /// </summary>
    Task<{Entity}?> GetByIdWithDetailsAsync(
        Guid id,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets an entity by a unique business key
    /// </summary>
    Task<{Entity}?> GetByNameAsync(
        string name,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all entities for a parent organization
    /// </summary>
    Task<IReadOnlyList<{Entity}>> GetByOrganizationIdAsync(
        Guid organizationId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all active entities
    /// </summary>
    Task<IReadOnlyList<{Entity}>> GetAllActiveAsync(
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Checks if an entity exists
    /// </summary>
    Task<bool> ExistsAsync(
        Guid id,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Checks if an entity with the given name exists
    /// </summary>
    Task<bool> ExistsByNameAsync(
        string name,
        CancellationToken cancellationToken = default);

    // ═══════════════════════════════════════════════════════════════
    // COMMAND METHODS (tracking only, no SaveChanges)
    // ═══════════════════════════════════════════════════════════════
    
    /// <summary>
    /// Adds a new entity to the context
    /// </summary>
    void Add({Entity} {entity});

    /// <summary>
    /// Adds multiple entities to the context
    /// </summary>
    void AddRange(IEnumerable<{Entity}> {entities});

    /// <summary>
    /// Updates an existing entity in the context
    /// </summary>
    void Update({Entity} {entity});

    /// <summary>
    /// Removes an entity from the context
    /// </summary>
    void Remove({Entity} {entity});

    /// <summary>
    /// Removes multiple entities from the context
    /// </summary>
    void RemoveRange(IEnumerable<{Entity}> {entities});
}

Template: Repository Implementation (Infrastructure Layer)

// src/{name}.infrastructure/Repositories/{Entity}Repository.cs
using Microsoft.EntityFrameworkCore;
using {name}.domain.{aggregate};

namespace {name}.infrastructure.repositories;

internal sealed class {Entity}Repository : I{Entity}Repository
{
    private readonly ApplicationDbContext _dbContext;

    public {Entity}Repository(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    // ═══════════════════════════════════════════════════════════════
    // QUERY METHODS
    // ═══════════════════════════════════════════════════════════════

    public async Task<{Entity}?> GetByIdAsync(
        Guid id,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .FirstOrDefaultAsync(e => e.Id == id, cancellationToken);
    }

    public async Task<{Entity}?> GetByIdWithDetailsAsync(
        Guid id,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .Include(e => e.{ChildEntities})
            .Include(e => e.{OtherRelation})
            .FirstOrDefaultAsync(e => e.Id == id, cancellationToken);
    }

    public async Task<{Entity}?> GetByNameAsync(
        string name,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .FirstOrDefaultAsync(
                e => e.Name.ToLower() == name.ToLower(),
                cancellationToken);
    }

    public async Task<IReadOnlyList<{Entity}>> GetByOrganizationIdAsync(
        Guid organizationId,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .Where(e => e.OrganizationId == organizationId)
            .OrderBy(e => e.Name)
            .ToListAsync(cancellationToken);
    }

    public async Task<IReadOnlyList<{Entity}>> GetAllActiveAsync(
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .Where(e => e.IsActive)
            .OrderBy(e => e.Name)
            .ToListAsync(cancellationToken);
    }

    public async Task<bool> ExistsAsync(
        Guid id,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .AnyAsync(e => e.Id == id, cancellationToken);
    }

    public async Task<bool> ExistsByNameAsync(
        string name,
        CancellationToken cancellationToken = default)
    {
        return await _dbContext
            .Set<{Entity}>()
            .AnyAsync(
                e => e.Name.ToLower() == name.ToLower(),
                cancellationToken);
    }

    // ═══════════════════════════════════════════════════════════════
    // COMMAND METHODS
    // ═══════════════════════════════════════════════════════════════

    public void Add({Entity} {entity})
    {
        _dbContext.Set<{Entity}>().Add({entity});
    }

    public void AddRange(IEnumerable<{Entity}> {entities})
    {
        _dbContext.Set<{Entity}>().AddRange({entities});
    }

    public void Update({Entity} {entity})
    {
        _dbContext.Set<{Entity}>().Update({entity});
    }

    public void Remove({Entity} {entity})
    {
        _dbContext.Set<{Entity}>().Remove({entity});
    }

    public void RemoveRange(IEnumerable<{Entity}> {entities})
    {
        _dbContext.Set<{Entity}>().RemoveRange({entities});
    }
}

Template: Repository with Child Entity Access

// src/{name}.domain/{Aggregate}/I{Entity}Repository.cs
namespace {name}.domain.{aggregate};

public interface I{Entity}Repository
{
    // Standard methods...

    // ═══════════════════════════════════════════════════════════════
    // CHILD ENTITY QUERIES (accessed through aggregate root)
    // ═══════════════════════════════════════════════════════════════

    /// <summary>
    /// Gets a child entity through its aggregate root
    /// </summary>
    Task<{ChildEntity}?> Get{ChildEntity}ByIdAsync(
        Guid {entity}Id,
        Guid {childEntity}Id,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all child entities
Compartilhar X LinkedIn