Skip to main content
The Infrastructure Layer provides concrete implementations of the repository pattern for both SQL and NoSQL databases.

SqlRepository (Entity Framework Core)

The BaseRepository<TEntity> in Core.Infraestructure.Repositories.Sql provides a SQL-based repository implementation using Entity Framework Core.

Class Definition

Core.Infraestructure.Repositories.Sql/BaseRepository.cs
namespace Core.Infraestructure.Repositories.Sql
{
    public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        public DbContext Context { get; private set; }
        public DbSet<TEntity> Repository { get; private set; }

        public BaseRepository(DbContext context)
        {
            Context = context;
            Repository = Context.Set<TEntity>();
        }
    }
}

Key Methods

Add Operations

public object Add(TEntity entity)
public async Task<object> AddAsync(TEntity entity)
Adds an entity to the database and returns the generated ID.

Query Operations

public List<TEntity> FindAll()
public async Task<List<TEntity>> FindAllAsync()
public TEntity FindOne(params object[] keyValues)
public async Task<TEntity> FindOneAsync(params object[] keyValues)
public long Count(Expression<Func<TEntity, bool>> filter)
public async Task<long> CountAsync(Expression<Func<TEntity, bool>> filter)

Update & Delete Operations

public void Update(object id, TEntity entity)
public void Remove(params object[] keyValues)

DbContext Configuration

Create a custom DbContext inheriting from Microsoft.EntityFrameworkCore.DbContext:
Infrastructure/Repositories/Sql/StoreDbContext.cs
internal class StoreDbContext : DbContext
{
    public DbSet<DummyEntity> DummyEntity { get; set; }

    public StoreDbContext(DbContextOptions<StoreDbContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<DummyEntity>().ToTable("DummyEntity");
    }
}

Creating a Concrete Repository

Infrastructure/Repositories/Sql/DummyEntityRepository.cs
internal sealed class DummyEntityRepository(StoreDbContext context) 
    : BaseRepository<DummyEntity>(context), IDummyEntityRepository
{
    // Inherit all base methods
    // Add custom methods specific to DummyEntity if needed
}

MongoDbRepository

The BaseRepository<TEntity> in Core.Infraestructure.Repositories.MongoDb provides a MongoDB-based repository implementation.

Class Definition

Core.Infraestructure.Repositories.MongoDb/BaseRepository.cs
namespace Core.Infraestructure.Repositories.MongoDb
{
    public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        public DbContext Context { get; private set; }
        public IMongoCollection<TEntity> Collection { get; private set; }

        public BaseRepository(DbContext context)
        {
            Context = context;
            Collection = Context.GetCollection<TEntity>();
        }
    }
}

Key Methods

Add Operations

public object Add(TEntity entity)
public async Task<object> AddAsync(TEntity entity)
Inserts a document and returns the ID (supports both Id and _id properties).

Query Operations

public List<TEntity> FindAll()
public async Task<List<TEntity>> FindAllAsync()
public TEntity FindOne(params object[] keyValues)
public async Task<TEntity> FindOneAsync(params object[] keyValues)
public long Count(Expression<Func<TEntity, bool>> filter)
public async Task<long> CountAsync(Expression<Func<TEntity, bool>> filter)

Update & Delete Operations

public void Update(object id, TEntity entity)
public void Remove(params object[] keyValues)

DbContext Configuration

Create a custom DbContext inheriting from Core.Infraestructure.Repositories.MongoDb.DbContext:
Infrastructure/Repositories/Mongo/StoreDbContext.cs
internal class StoreDbContext : DbContext
{
    public StoreDbContext(string connectionString) : base(connectionString)
    {
        MapTypes();
    }

    public override IMongoCollection<T> GetCollection<T>()
    {
        if (typeof(T) == typeof(DummyEntity))
            return Database.GetCollection<T>(DummyEntityMap.GetCollectionName());
        return null;
    }

    private static void MapTypes()
    {
        DummyEntityMap.Configure();
    }
}

Creating a Concrete Repository

Infrastructure/Repositories/Mongo/DummyEntityRepository.cs
internal sealed class DummyEntityRepository : BaseRepository<DummyEntity>, IDummyEntityRepository
{
    public DummyEntityRepository(StoreDbContext context) : base(context)
    {
    }
}

Repository Registration

Repositories are registered in the DI container based on the configured database type:
Infrastructure/Factories/DatabaseFactory.cs
internal static class DatabaseFactory
{
    public static void CreateDataBase(this IServiceCollection services, string dbType, IConfiguration configuration)
    {
        switch (dbType.ToEnum<DatabaseType>())
        {
            case DatabaseType.MYSQL:
            case DatabaseType.MARIADB:
            case DatabaseType.SQLSERVER:
                services.AddSqlServerRepositories(configuration);
                break;
            case DatabaseType.MONGODB:
                services.AddMongoDbRepositories(configuration);
                break;
        }
    }
}

SQL Repository Registration

private static IServiceCollection AddSqlServerRepositories(
    this IServiceCollection services, 
    IConfiguration configuration)
{
    services.AddDbContext<Repositories.Sql.StoreDbContext>(options =>
    {
        options.UseSqlServer(configuration.GetConnectionString("SqlConnection"));
    }, ServiceLifetime.Scoped);

    // Enable migrations
    var context = services.BuildServiceProvider()
        .GetRequiredService<Repositories.Sql.StoreDbContext>();
    context.Database.Migrate();

    // Register repositories
    services.AddTransient<IDummyEntityRepository, Repositories.Sql.DummyEntityRepository>();

    return services;
}

MongoDB Repository Registration

private static IServiceCollection AddMongoDbRepositories(
    this IServiceCollection services, 
    IConfiguration configuration)
{
    // Configure naming conventions
    ConventionRegistry.Register("Camel Case", 
        new ConventionPack { new CamelCaseElementNameConvention() }, 
        _ => true);

    // Register DbContext as singleton
    Repositories.Mongo.StoreDbContext db = new(
        configuration.GetConnectionString("MongoConnection"));
    services.AddSingleton(typeof(Repositories.Mongo.StoreDbContext), db);

    // Register repositories
    services.AddTransient<IDummyEntityRepository, Repositories.Mongo.DummyEntityRepository>();

    return services;
}

Configuration

Set the database type in appsettings.json:
{
  "Configurations": {
    "UseDatabase": "SQLSERVER"  // or "MONGODB", "MYSQL", "MARIADB"
  },
  "ConnectionStrings": {
    "SqlConnection": "Server=localhost;Database=MyDb;Trusted_Connection=True;",
    "MongoConnection": "mongodb://localhost:27017/MyDb"
  }
}

Usage Example

public class MyService
{
    private readonly IDummyEntityRepository _repository;

    public MyService(IDummyEntityRepository repository)
    {
        _repository = repository;
    }

    public async Task<DummyEntity> GetEntityAsync(int id)
    {
        return await _repository.FindOneAsync(id);
    }

    public async Task<object> CreateEntityAsync(DummyEntity entity)
    {
        return await _repository.AddAsync(entity);
    }
}

Key Features

  • Database Abstraction: Switch between SQL and MongoDB without changing application code
  • Async Support: All operations have async variants
  • Type Safety: Strongly-typed repository pattern
  • Automatic Migrations: SQL repositories support EF Core migrations
  • Convention-based: MongoDB repositories support naming conventions

Build docs developers (and LLMs) love