![]() |
VOOZH | about |
dotnet add package MongoDB.Abstracts --version 7.2.0
NuGet\Install-Package MongoDB.Abstracts -Version 7.2.0
<PackageReference Include="MongoDB.Abstracts" Version="7.2.0" />
<PackageVersion Include="MongoDB.Abstracts" Version="7.2.0" />Directory.Packages.props
<PackageReference Include="MongoDB.Abstracts" />Project file
paket add MongoDB.Abstracts --version 7.2.0
#r "nuget: MongoDB.Abstracts, 7.2.0"
#:package MongoDB.Abstracts@7.2.0
#addin nuget:?package=MongoDB.Abstracts&version=7.2.0Install as a Cake Addin
#tool nuget:?package=MongoDB.Abstracts&version=7.2.0Install as a Cake Tool
A modern .NET library that provides abstract base classes and interfaces for implementing the repository pattern with MongoDB. Simplify your MongoDB data access layer with strongly-typed repositories, automatic auditing, and dependency injection support.
👁 Build status
👁 NuGet Version
👁 Coverage Status
Install-Package MongoDB.Abstracts
dotnet add package MongoDB.Abstracts
<PackageReference Include="MongoDB.Abstracts" />
More information available at nuget.org/packages/MongoDB.Abstracts
IMongoEntity - Base interface for MongoDB entities with Id, Created, and Updated propertiesMongoEntity - Base class implementing IMongoEntity with common MongoDB entity behaviorIMongoQuery<TEntity, TKey> - Interface for generic MongoDB query operationsIMongoRepository<TEntity, TKey> - Interface for generic MongoDB repository operationsIMongoEntityRepository<TEntity> - Specialized repository interface for IMongoEntity typesIMongoEntityRepository<TDiscriminator, TEntity> - Multi-database discriminator supportMongoQuery<TEntity, TKey> - Base class for MongoDB query operationsMongoRepository<TEntity, TKey> - Base class for MongoDB repository operationsMongoEntityRepository<TEntity> - Entity-specific repository implementationRegister MongoDB repositories with dependency injection using a connection string:
// Direct connection string
services.AddMongoRepository("mongodb://localhost:27017/MyDatabase");
// Connection string from configuration
services.AddMongoRepository("MyDatabase");
appsettings.json:
{
"ConnectionStrings": {
"MyDatabase": "mongodb://localhost:27017/MyDatabase"
}
}
You can customize the MongoDB client settings, including logging configuration:
using Microsoft.Extensions.Logging;
using MongoDB.Driver.Core.Configuration;
services.AddMongoRepository(
nameOrConnectionString: "MyDatabase",
configuration: (provider, settings) =>
{
// Enable MongoDB driver logging
var loggerFactory = provider.GetService<ILoggerFactory>();
settings.LoggingSettings = new LoggingSettings(loggerFactory);
// Configure other client settings
settings.ConnectTimeout = TimeSpan.FromSeconds(30);
settings.ServerSelectionTimeout = TimeSpan.FromSeconds(30);
settings.MaxConnectionPoolSize = 100;
}
);
Override the database name from the connection string:
services.AddMongoRepository(
nameOrConnectionString: "mongodb://localhost:27017/DefaultDb",
databaseName: "ActualDatabase"
);
For applications requiring multiple MongoDB connections, use discriminator types to distinguish between different database contexts:
public readonly struct ProductsConnection;
public readonly struct InventoryConnection;
public readonly struct UsersConnection;
services.AddMongoRepository<ProductsConnection>("ProductsConnection");
services.AddMongoRepository<InventoryConnection>("InventoryConnection");
services.AddMongoRepository<UsersConnection>("UsersConnection");
appsettings.json:
{
"ConnectionStrings": {
"ProductsConnection": "mongodb://localhost:27017/Products",
"InventoryConnection": "mongodb://localhost:27017/Inventory",
"UsersConnection": "mongodb://localhost:27017/Users"
}
}
public class ProductService
{
private readonly IMongoEntityRepository<ProductsConnection, Product> _repository;
public ProductService(IMongoEntityRepository<ProductsConnection, Product> repository)
{
_repository = repository;
}
public async Task<Product> GetProductAsync(string id)
{
return await _repository.FindAsync(id);
}
}
public class InventoryService
{
private readonly IMongoEntityRepository<InventoryConnection, Inventory> _repository;
public InventoryService(IMongoEntityRepository<InventoryConnection, Inventory> repository)
{
_repository = repository;
}
public async Task<List<Inventory>> GetLowStockItemsAsync()
{
return await _repository.FindAllAsync(i => i.Quantity < 10);
}
}
public class Product : MongoEntity
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public decimal Price { get; set; }
public int Stock { get; set; }
public string Category { get; set; } = string.Empty;
public bool IsActive { get; set; } = true;
}
var productRepo = serviceProvider.GetRequiredService<IMongoEntityRepository<Product>>();
var product = new Product
{
Name = "Gaming Laptop",
Description = "High-performance gaming laptop",
Price = 1299.99m,
Stock = 5,
Category = "Electronics"
};
var createdProduct = await productRepo.InsertAsync(product);
Console.WriteLine($"Created product with ID: {createdProduct.Id}");
// Find by ID
var product = await productRepo.FindAsync("67a0dc52fa5ebe49f293a374");
// Find single entity with query
var expensiveProduct = await productRepo.FindOneAsync(p => p.Price > 1000);
// Find multiple entities
var electronicsProducts = await productRepo.FindAllAsync(p => p.Category == "Electronics");
// Find with LINQ
var activeProducts = productRepo.All()
.Where(p => p.IsActive && p.Stock > 0)
.OrderBy(p => p.Name)
.ToListAsync();
// Find and update
var product = await productRepo.FindAsync("67a0dc52fa5ebe49f293a374");
if (product != null)
{
product.Price = 1199.99m;
product.Stock = 3;
var updatedProduct = await productRepo.UpdateAsync(product);
Console.WriteLine($"Updated product: {updatedProduct.Name}");
}
// Delete by ID
var deletedCount = await productRepo.DeleteAsync("67a0dc52fa5ebe49f293a374");
Console.WriteLine($"Deleted {deletedCount} product(s)");
// Delete with query
var deletedInactiveCount = await productRepo.DeleteAllAsync(p => !p.IsActive);
Console.WriteLine($"Deleted {deletedInactiveCount} inactive product(s)");
var productRepo = serviceProvider.GetRequiredService<IMongoEntityRepository<Product>>();
// Complex filtering with pagination
var expensiveElectronics = await productRepo.All()
.Where(p => p.Category == "Electronics" && p.Price > 500)
.Where(p => p.IsActive && p.Stock > 0)
.OrderByDescending(p => p.Price)
.ThenBy(p => p.Name)
.Skip(0)
.Take(10)
.ToListAsync();
// Aggregation-style queries
var categoryStats = productRepo.All()
.Where(p => p.IsActive)
.GroupBy(p => p.Category)
.Select(g => new
{
Category = g.Key,
Count = g.Count(),
AveragePrice = g.Average(p => p.Price),
TotalValue = g.Sum(p => p.Price * p.Stock)
})
.ToList();
using MongoDB.Driver;
// Using MongoDB.Driver filters for advanced scenarios
var filter = Builders<Product>.Filter.And(
Builders<Product>.Filter.Eq(p => p.Category, "Electronics"),
Builders<Product>.Filter.Gte(p => p.Price, 100),
Builders<Product>.Filter.Lte(p => p.Price, 1000)
);
var products = await productRepo.FindAllAsync(filter);
Create specialized repositories by inheriting from the base classes:
public class ProductRepository : MongoEntityRepository<Product>
{
public ProductRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase)
{
}
// Custom business logic before insert
protected override void BeforeInsert(Product entity)
{
base.BeforeInsert(entity);
// Auto-generate SKU
entity.SKU = GenerateSKU(entity.Category, entity.Name);
// Validate business rules
ValidateProductRules(entity);
}
// Custom business logic before update
protected override void BeforeUpdate(Product entity)
{
base.BeforeUpdate(entity);
// Re-validate business rules
ValidateProductRules(entity);
// Update search tags
entity.SearchTags = GenerateSearchTags(entity);
}
// Ensure custom indexes
protected override void EnsureIndexes(IMongoCollection<Product> mongoCollection)
{
base.EnsureIndexes(mongoCollection);
// Create compound index for category and price
mongoCollection.Indexes.CreateOne(
new CreateIndexModel<Product>(
Builders<Product>.IndexKeys
.Ascending(p => p.Category)
.Descending(p => p.Price),
new CreateIndexOptions { Name = "category_price_idx" }
)
);
// Create text index for search
mongoCollection.Indexes.CreateOne(
new CreateIndexModel<Product>(
Builders<Product>.IndexKeys.Text(p => p.Name).Text(p => p.Description),
new CreateIndexOptions { Name = "text_search_idx" }
)
);
// Create unique index on SKU
mongoCollection.Indexes.CreateOne(
new CreateIndexModel<Product>(
Builders<Product>.IndexKeys.Ascending(p => p.SKU),
new CreateIndexOptions { Unique = true, Name = "sku_unique_idx" }
)
);
}
// Custom repository methods
public async Task<List<Product>> FindByPriceRangeAsync(decimal minPrice, decimal maxPrice)
{
return await FindAllAsync(p => p.Price >= minPrice && p.Price <= maxPrice && p.IsActive);
}
public async Task<Product?> FindBySKUAsync(string sku)
{
return await FindOneAsync(p => p.SKU == sku);
}
public async Task<bool> IsStockAvailableAsync(string productId, int requestedQuantity)
{
var product = await FindAsync(productId);
return product?.Stock >= requestedQuantity;
}
private string GenerateSKU(string category, string name)
{
// Implementation for SKU generation
var categoryCode = category.ToUpperInvariant().Substring(0, Math.Min(3, category.Length));
var nameCode = string.Concat(name.Where(char.IsLetterOrDigit)).ToUpperInvariant();
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
return $"{categoryCode}-{nameCode}-{timestamp}";
}
private void ValidateProductRules(Product entity)
{
if (entity.Price <= 0)
throw new ArgumentException("Product price must be greater than zero");
if (string.IsNullOrWhiteSpace(entity.Name))
throw new ArgumentException("Product name is required");
if (entity.Stock < 0)
throw new ArgumentException("Product stock cannot be negative");
}
private List<string> GenerateSearchTags(Product entity)
{
var tags = new List<string>();
// Add category tags
tags.Add(entity.Category.ToLowerInvariant());
// Add name words
tags.AddRange(entity.Name.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Select(w => w.ToLowerInvariant()));
// Add price range tags
if (entity.Price < 50) tags.Add("budget");
else if (entity.Price > 1000) tags.Add("premium");
else tags.Add("mid-range");
return tags.Distinct().ToList();
}
}
The IMongoEntity interface automatically provides auditing capabilities:
public class AuditableProduct : MongoEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
// Additional audit fields (beyond base Created/Updated)
public string CreatedBy { get; set; } = string.Empty;
public string UpdatedBy { get; set; } = string.Empty;
}
public class AuditableProductRepository : MongoEntityRepository<AuditableProduct>
{
private readonly ICurrentUserService _currentUserService;
public AuditableProductRepository(
IMongoDatabase mongoDatabase,
ICurrentUserService currentUserService)
: base(mongoDatabase)
{
_currentUserService = currentUserService;
}
protected override void BeforeInsert(AuditableProduct entity)
{
base.BeforeInsert(entity); // Sets Created and Updated timestamps
entity.CreatedBy = _currentUserService.GetCurrentUserId();
}
protected override void BeforeUpdate(AuditableProduct entity)
{
base.BeforeUpdate(entity); // Updates the Updated timestamp
entity.UpdatedBy = _currentUserService.GetCurrentUserId();
}
}
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 netstandard2.1 is compatible. |
| .NET Framework | net472 net472 is compatible. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 2 NuGet packages that depend on MongoDB.Abstracts:
| Package | Downloads |
|---|---|
|
MediatR.CommandQuery.MongoDB
CQRS framework based on MediatR |
|
|
Arbiter.CommandQuery.MongoDB
Command Query Responsibility Segregation (CQRS) framework based on mediator pattern using Mongo DB as the data store handler |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.2.0 | 297 | 5/28/2026 |
| 7.1.2 | 400 | 5/13/2026 |
| 7.1.1 | 2,375 | 1/20/2026 |
| 7.1.0 | 720 | 12/13/2025 |
| 7.0.0 | 183 | 12/12/2025 |
| 6.8.0 | 243 | 12/12/2025 |
| 6.7.0 | 853 | 11/12/2025 |
| 6.6.0 | 737 | 9/3/2025 |
| 6.5.0 | 845 | 5/25/2025 |
| 6.4.0 | 434 | 4/18/2025 |
| 6.3.0 | 588 | 2/4/2025 |
| 6.2.0 | 225 | 2/4/2025 |
| 6.1.0 | 233 | 2/3/2025 |
| 6.0.0 | 224 | 2/3/2025 |
| 5.7.1 | 914 | 7/26/2024 |
| 5.7.0 | 683 | 5/10/2024 |
| 5.6.1 | 948 | 7/28/2023 |
| 5.5.269 | 1,389 | 12/28/2022 |
| 5.5.219 | 1,093 | 4/23/2022 |
| 5.5.216 | 809 | 3/21/2022 |