Marventa.Framework
3.3.2
See the version list below for details.
dotnet add package Marventa.Framework --version 3.3.2
NuGet\Install-Package Marventa.Framework -Version 3.3.2
<PackageReference Include="Marventa.Framework" Version="3.3.2" />
<PackageVersion Include="Marventa.Framework" Version="3.3.2" />
<PackageReference Include="Marventa.Framework" />
paket add Marventa.Framework --version 3.3.2
#r "nuget: Marventa.Framework, 3.3.2"
#:package Marventa.Framework@3.3.2
#addin nuget:?package=Marventa.Framework&version=3.3.2
#tool nuget:?package=Marventa.Framework&version=3.3.2
π Marventa Framework
Enterprise-grade .NET framework with Clean Architecture, CQRS, and 47+ modular features
π Table of Contents
- Quick Start
- Core Features
- Installation & Setup
- Entity Base Classes
- CQRS Pattern
- Repository Pattern
- Configuration Options
- Real-World Example
- Documentation
- Support
β‘ Quick Start
1. Installation
dotnet add package Marventa.Framework
2. Configure Services
using Marventa.Framework.Web.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add Marventa Framework with CQRS
builder.Services.AddMarventaFramework(builder.Configuration, options =>
{
// Core Infrastructure
options.EnableLogging = true;
options.EnableCaching = true;
options.EnableRepository = true;
options.EnableHealthChecks = true;
// CQRS + MediatR
options.EnableCQRS = true;
options.CqrsOptions.Assemblies.Add(typeof(Program).Assembly);
options.CqrsOptions.EnableValidationBehavior = true;
options.CqrsOptions.EnableLoggingBehavior = true;
options.CqrsOptions.EnableTransactionBehavior = true;
});
var app = builder.Build();
app.UseMarventaFramework(builder.Configuration);
app.Run();
3. Create Your First Entity
using Marventa.Framework.Core.Entities;
public class Product : BaseEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public int StockQuantity { get; set; }
// BaseEntity provides:
// - Guid Id (auto-generated)
// - DateTime CreatedDate, UpdatedDate
// - bool IsDeleted (soft delete)
// - Audit tracking (CreatedBy, UpdatedBy)
}
4. Done! π
You now have:
- β Repository pattern with Unit of Work
- β CQRS with automatic validation
- β Soft delete and audit tracking
- β Logging and health checks
- β Clean Architecture structure
π― Core Features
1. Base Entity Classes
| Class | Purpose | When to Use |
|---|---|---|
BaseEntity |
Basic entity with audit tracking | Default for all entities |
AuditableEntity |
Adds versioning & concurrency | Entities needing version control |
TenantBaseEntity |
Multi-tenant isolation | Multi-tenant applications |
2. CQRS + MediatR Pipeline
// Command with automatic validation & transaction
public class CreateProductCommand : ICommand<Guid>
{
public string Name { get; set; }
public decimal Price { get; set; }
}
// Validator (automatically executed)
public class CreateProductCommandValidator : AbstractValidator<CreateProductCommand>
{
public CreateProductCommandValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
RuleFor(x => x.Price).GreaterThan(0);
}
}
// Handler (transaction managed automatically)
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, Guid>
{
private readonly IUnitOfWork _unitOfWork;
public CreateProductCommandHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task<Guid> Handle(CreateProductCommand request, CancellationToken ct)
{
var product = new Product { Name = request.Name, Price = request.Price };
await _unitOfWork.Repository<Product>().AddAsync(product, ct);
// SaveChanges called automatically by TransactionBehavior
return product.Id;
}
}
3. Repository Pattern
public class ProductService
{
private readonly IRepository<Product> _repository;
public ProductService(IRepository<Product> repository)
{
_repository = repository;
}
// Simple queries
public async Task<Product?> GetByIdAsync(Guid id)
=> await _repository.GetByIdAsync(id);
// Advanced queries with specifications
public async Task<IEnumerable<Product>> GetExpensiveProductsAsync()
=> await _repository.FindAsync(p => p.Price > 1000);
// Pagination
public async Task<IEnumerable<Product>> GetPagedAsync(int page, int size)
=> await _repository.GetPagedAsync(page, size);
}
4. Built-in Pipeline Behaviors
| Behavior | Purpose | Automatic Actions |
|---|---|---|
ValidationBehavior |
Input validation | Validates using FluentValidation |
LoggingBehavior |
Performance monitoring | Logs execution time, warns if >500ms |
TransactionBehavior |
Transaction management | Auto SaveChanges, rollback on error |
IdempotencyBehavior |
Duplicate prevention | Prevents duplicate command execution |
π¦ Installation & Setup
Step 1: Install Package
dotnet add package Marventa.Framework
Step 2: Configure appsettings.json
{
"Marventa": {
"ApiKey": "your-secret-key",
"RateLimit": {
"MaxRequests": 100,
"WindowMinutes": 15
},
"Caching": {
"Provider": "Memory"
}
},
"ConnectionStrings": {
"DefaultConnection": "your-database-connection"
}
}
Step 3: Setup DbContext
using Marventa.Framework.Infrastructure.Data;
public class ApplicationDbContext : BaseDbContext
{
public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options,
ITenantContext tenantContext)
: base(options, tenantContext)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); // IMPORTANT: Apply base configurations
modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
}
}
BaseDbContext provides:
- β Automatic audit tracking (CreatedDate, UpdatedDate)
- β Soft delete with global query filters
- β Multi-tenancy support with automatic isolation
- β Domain event dispatching
- β Optimistic concurrency with RowVersion
ποΈ Entity Base Classes
BaseEntity - Standard Entities
using Marventa.Framework.Core.Entities;
public class Product : BaseEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
// Provides automatically:
// - Guid Id
// - DateTime CreatedDate, UpdatedDate
// - string? CreatedBy, UpdatedBy
// - bool IsDeleted (soft delete)
// - DateTime? DeletedDate, string? DeletedBy
AuditableEntity - With Versioning
public class Order : AuditableEntity
{
public string OrderNumber { get; set; } = string.Empty;
public decimal TotalAmount { get; set; }
}
// Includes BaseEntity + versioning:
// - string Version (semantic versioning)
// - byte[] RowVersion (optimistic concurrency)
TenantBaseEntity - Multi-Tenant
public class Customer : TenantBaseEntity
{
public string CompanyName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
// Includes BaseEntity + tenant isolation:
// - Guid TenantId
// - Automatic filtering by tenant in all queries
β‘ CQRS Pattern
Commands (Write Operations)
using Marventa.Framework.Application.Commands;
// 1. Define Command
public class UpdateProductPriceCommand : ICommand<bool>
{
public Guid ProductId { get; set; }
public decimal NewPrice { get; set; }
}
// 2. Validator (optional but recommended)
public class UpdateProductPriceCommandValidator : AbstractValidator<UpdateProductPriceCommand>
{
public UpdateProductPriceCommandValidator()
{
RuleFor(x => x.ProductId).NotEmpty();
RuleFor(x => x.NewPrice).GreaterThan(0).LessThan(1000000);
}
}
// 3. Handler
public class UpdateProductPriceCommandHandler : IRequestHandler<UpdateProductPriceCommand, bool>
{
private readonly IUnitOfWork _unitOfWork;
public async Task<bool> Handle(UpdateProductPriceCommand request, CancellationToken ct)
{
var product = await _unitOfWork.Repository<Product>().GetByIdAsync(request.ProductId);
if (product == null) return false;
product.Price = request.NewPrice;
await _unitOfWork.Repository<Product>().UpdateAsync(product);
return true;
}
}
Queries (Read Operations)
using Marventa.Framework.Application.Queries;
// 1. Define Query
public class GetProductByIdQuery : IQuery<ProductDto>
{
public Guid Id { get; set; }
}
// 2. Handler
public class GetProductByIdQueryHandler : IRequestHandler<GetProductByIdQuery, ProductDto>
{
private readonly IRepository<Product> _repository;
public async Task<ProductDto> Handle(GetProductByIdQuery request, CancellationToken ct)
{
var product = await _repository.GetByIdAsync(request.Id);
return new ProductDto
{
Id = product.Id,
Name = product.Name,
Price = product.Price
};
}
}
Using in Controllers
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IMediator _mediator;
public ProductsController(IMediator mediator) => _mediator = mediator;
[HttpGet("{id}")]
public async Task<ActionResult<ProductDto>> Get(Guid id)
{
var query = new GetProductByIdQuery { Id = id };
var result = await _mediator.Send(query);
return Ok(result);
}
[HttpPost]
public async Task<ActionResult<Guid>> Create(CreateProductCommand command)
{
var id = await _mediator.Send(command);
return CreatedAtAction(nameof(Get), new { id }, id);
}
}
πΎ Repository Pattern
Basic Usage
public class ProductService
{
private readonly IRepository<Product> _repository;
// CRUD Operations
public async Task<Product> CreateAsync(Product product)
=> await _repository.AddAsync(product);
public async Task<Product?> GetAsync(Guid id)
=> await _repository.GetByIdAsync(id);
public async Task<IEnumerable<Product>> GetAllAsync()
=> await _repository.GetAllAsync();
public async Task UpdateAsync(Product product)
=> await _repository.UpdateAsync(product);
public async Task DeleteAsync(Product product)
=> await _repository.DeleteAsync(product); // Soft delete
}
Advanced Queries
// Find with predicate
var products = await _repository.FindAsync(p => p.Price > 100);
// Pagination
var pagedProducts = await _repository.GetPagedAsync(pageNumber: 1, pageSize: 20);
// Count
var count = await _repository.CountAsync(p => p.IsDeleted == false);
// Any
var hasExpensive = await _repository.AnyAsync(p => p.Price > 1000);
Unit of Work Pattern
public class OrderService
{
private readonly IUnitOfWork _unitOfWork;
public async Task<Order> CreateOrderAsync(OrderDto dto)
{
await _unitOfWork.BeginTransactionAsync();
try
{
// Create order
var order = new Order { OrderNumber = dto.OrderNumber };
await _unitOfWork.Repository<Order>().AddAsync(order);
// Update inventory
var product = await _unitOfWork.Repository<Product>().GetByIdAsync(dto.ProductId);
product.StockQuantity -= dto.Quantity;
await _unitOfWork.SaveChangesAsync();
await _unitOfWork.CommitTransactionAsync();
return order;
}
catch
{
await _unitOfWork.RollbackTransactionAsync();
throw;
}
}
}
βοΈ Configuration Options
Feature Flags (47 Total)
builder.Services.AddMarventaFramework(builder.Configuration, options =>
{
// ποΈ Core Infrastructure
options.EnableLogging = true;
options.EnableCaching = true;
options.EnableRepository = true;
options.EnableHealthChecks = true;
options.EnableValidation = true;
options.EnableExceptionHandling = true;
// π‘οΈ Security
options.EnableSecurity = true;
options.EnableJWT = true;
options.EnableApiKeys = true;
options.EnableEncryption = true;
// β‘ CQRS + MediatR
options.EnableCQRS = true;
options.CqrsOptions.EnableValidationBehavior = true;
options.CqrsOptions.EnableLoggingBehavior = true;
options.CqrsOptions.EnableTransactionBehavior = true;
// π API Management
options.EnableVersioning = true;
options.EnableRateLimiting = true;
options.EnableCompression = true;
options.EnableIdempotency = true;
// π Monitoring
options.EnableAnalytics = true;
options.EnableObservability = true;
// π Event-Driven
options.EnableEventDriven = true;
options.EnableMessaging = true;
options.EnableSagas = true;
// π’ Multi-Tenancy
options.EnableMultiTenancy = true;
});
π Real-World Example
Complete working example of a Product Management API:
// 1. Entity
public class Product : BaseEntity
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public decimal Price { get; set; }
public int StockQuantity { get; set; }
public string Category { get; set; } = string.Empty;
}
// 2. Command
public class CreateProductCommand : ICommand<Guid>
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public decimal Price { get; set; }
public int StockQuantity { get; set; }
public string Category { get; set; } = string.Empty;
}
// 3. Validator
public class CreateProductCommandValidator : AbstractValidator<CreateProductCommand>
{
public CreateProductCommandValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
RuleFor(x => x.Price).GreaterThan(0);
RuleFor(x => x.StockQuantity).GreaterThanOrEqualTo(0);
RuleFor(x => x.Category).NotEmpty();
}
}
// 4. Handler
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, Guid>
{
private readonly IUnitOfWork _unitOfWork;
public CreateProductCommandHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task<Guid> Handle(CreateProductCommand request, CancellationToken ct)
{
var product = new Product
{
Name = request.Name,
Description = request.Description,
Price = request.Price,
StockQuantity = request.StockQuantity,
Category = request.Category
};
await _unitOfWork.Repository<Product>().AddAsync(product, ct);
// TransactionBehavior automatically calls SaveChangesAsync
return product.Id;
}
}
// 5. Query
public class GetAllProductsQuery : IQuery<IEnumerable<ProductDto>>
{
public string? Category { get; set; }
public decimal? MinPrice { get; set; }
public decimal? MaxPrice { get; set; }
}
// 6. Query Handler
public class GetAllProductsQueryHandler : IRequestHandler<GetAllProductsQuery, IEnumerable<ProductDto>>
{
private readonly IRepository<Product> _repository;
public async Task<IEnumerable<ProductDto>> Handle(GetAllProductsQuery request, CancellationToken ct)
{
var query = _repository.Query();
if (!string.IsNullOrEmpty(request.Category))
query = query.Where(p => p.Category == request.Category);
if (request.MinPrice.HasValue)
query = query.Where(p => p.Price >= request.MinPrice.Value);
if (request.MaxPrice.HasValue)
query = query.Where(p => p.Price <= request.MaxPrice.Value);
var products = await query.ToListAsync(ct);
return products.Select(p => new ProductDto
{
Id = p.Id,
Name = p.Name,
Price = p.Price,
StockQuantity = p.StockQuantity,
Category = p.Category
});
}
}
// 7. Controller
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IMediator _mediator;
public ProductsController(IMediator mediator) => _mediator = mediator;
[HttpGet]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll([FromQuery] GetAllProductsQuery query)
{
var products = await _mediator.Send(query);
return Ok(products);
}
[HttpPost]
public async Task<ActionResult<Guid>> Create([FromBody] CreateProductCommand command)
{
var id = await _mediator.Send(command);
return CreatedAtAction(nameof(GetById), new { id }, id);
}
[HttpGet("{id}")]
public async Task<ActionResult<ProductDto>> GetById(Guid id)
{
var query = new GetProductByIdQuery { Id = id };
var product = await _mediator.Send(query);
return product != null ? Ok(product) : NotFound();
}
}
π Documentation
Complete Resources
- π Full Documentation - Comprehensive guide
- π Getting Started Tutorial - Step-by-step guide
- π‘ Sample Projects - Working examples
- π§ API Reference - Complete API docs
- π Migration Guide - Upgrade instructions
Key Topics
- Clean Architecture Implementation
- CQRS Pattern with MediatR
- Repository & Unit of Work
- Multi-Tenancy Setup
- Event-Driven Architecture
- Saga Pattern for Distributed Transactions
- CDN Integration (Azure, AWS, CloudFlare)
- Performance Optimization
π Support
Get Help
- π¬ GitHub Discussions - Ask questions
- π Report Issues - Bug reports
- π§ Email: ademkinatas@gmail.com
- β Star on GitHub - Show your support!
Quick Links
π License
MIT License - Free for personal and commercial use.
See LICENSE for details.
<div align="center">
Built with β€οΈ by Adem KΔ±nataΕ
β Star us on GitHub if you find this useful!
</div>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 5.2.0 | 268 | 10/13/2025 | |
| 5.1.0 | 293 | 10/5/2025 | |
| 5.0.0 | 206 | 10/4/2025 | |
| 4.6.0 | 213 | 10/3/2025 | |
| 4.5.5 | 236 | 10/2/2025 | |
| 4.5.4 | 232 | 10/2/2025 | |
| 4.5.3 | 225 | 10/2/2025 | |
| 4.5.2 | 226 | 10/2/2025 | |
| 4.5.1 | 230 | 10/2/2025 | |
| 4.5.0 | 230 | 10/2/2025 | |
| 4.4.0 | 237 | 10/1/2025 | |
| 4.3.0 | 235 | 10/1/2025 | |
| 4.2.0 | 234 | 10/1/2025 | |
| 4.1.0 | 224 | 10/1/2025 | |
| 4.0.2 | 236 | 10/1/2025 | |
| 4.0.1 | 227 | 10/1/2025 | |
| 4.0.0 | 302 | 9/30/2025 | |
| 3.5.2 | 234 | 9/30/2025 | |
| 3.5.1 | 268 | 9/30/2025 | |
| 3.4.1 | 273 | 9/30/2025 | |
| 3.4.0 | 266 | 9/30/2025 | |
| 3.3.2 | 275 | 9/30/2025 | |
| 3.2.0 | 271 | 9/30/2025 | |
| 3.1.0 | 266 | 9/29/2025 | |
| 3.0.1 | 271 | 9/29/2025 | |
| 3.0.1-preview-20250929165802 | 257 | 9/29/2025 | |
| 3.0.0 | 265 | 9/29/2025 | |
| 3.0.0-preview-20250929164242 | 265 | 9/29/2025 | |
| 3.0.0-preview-20250929162455 | 261 | 9/29/2025 | |
| 2.12.0-preview-20250929161039 | 254 | 9/29/2025 | |
| 2.11.0 | 273 | 9/29/2025 | |
| 2.10.0 | 268 | 9/29/2025 | |
| 2.9.0 | 261 | 9/29/2025 | |
| 2.8.0 | 262 | 9/29/2025 | |
| 2.7.0 | 276 | 9/29/2025 | |
| 2.6.0 | 268 | 9/28/2025 | |
| 2.5.0 | 277 | 9/28/2025 | |
| 2.4.0 | 267 | 9/28/2025 | |
| 2.3.0 | 267 | 9/28/2025 | |
| 2.2.0 | 281 | 9/28/2025 | |
| 2.1.0 | 269 | 9/26/2025 | |
| 2.0.9 | 273 | 9/26/2025 | |
| 2.0.5 | 268 | 9/25/2025 | |
| 2.0.4 | 271 | 9/25/2025 | |
| 2.0.3 | 276 | 9/25/2025 | |
| 2.0.1 | 277 | 9/25/2025 | |
| 2.0.0 | 273 | 9/25/2025 | |
| 1.1.2 | 353 | 9/24/2025 | |
| 1.1.1 | 354 | 9/24/2025 | |
| 1.1.0 | 271 | 9/24/2025 | |
| 1.0.0 | 273 | 9/24/2025 |
v3.3.2: Clean Build - Fixed all build warnings. Added XML documentation to Analytics classes. Updated analyzers to 9.0.0. CI/CD workflows optimized. Zero warnings in production builds. No breaking changes - fully backward compatible.