Marventa.Framework 4.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Marventa.Framework --version 4.0.1
                    
NuGet\Install-Package Marventa.Framework -Version 4.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Marventa.Framework" Version="4.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Marventa.Framework" Version="4.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Marventa.Framework" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Marventa.Framework --version 4.0.1
                    
#r "nuget: Marventa.Framework, 4.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Marventa.Framework@4.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Marventa.Framework&version=4.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Marventa.Framework&version=4.0.1
                    
Install as a Cake Tool

Marventa.Framework v4.0.1

Enterprise-grade .NET 8.0 & 9.0 framework for building scalable microservices with DDD, CQRS, and Event-Driven Architecture.

NuGet License: MIT

Complete architectural redesign with single-package approach!

๐Ÿ’ก We strongly recommend using v4.0.1 for all new projects. This version provides a unified, production-ready architecture with complete feature set, simplified dependency management, and superior performance compared to previous versions.

Breaking Changes

  • โš ๏ธ Complete restructure from multi-project to single-project architecture
  • โš ๏ธ All features now in one unified package: Marventa.Framework
  • โš ๏ธ Namespace changes for better organization
  • โš ๏ธ Requires .NET 8.0 or .NET 9.0
  • โš ๏ธ Migration required from v3.x and earlier versions

What's New in v4.0.1

  • โœจ Unified single-package architecture - One package, all features
  • โœจ Multi-targeting support: .NET 8.0 (LTS) and .NET 9.0
  • โœจ Simplified dependency management - No more version conflicts
  • โœจ Enhanced performance and efficiency
  • โœจ Complete CQRS, Event-Driven, and DDD implementation
  • โœจ Enterprise-ready patterns out of the box
  • โœจ Full Kafka support for high-throughput event streaming
  • โœจ OpenTelemetry integration for distributed tracing
  • โœจ MongoDB support for NoSQL scenarios
  • โœจ Cloud storage providers (Azure Blob, AWS S3)
  • โœจ Built-in rate limiting middleware
  • โœจ MassTransit integration for advanced messaging patterns
  • โœจ Comprehensive logging with Serilog + Elasticsearch

๐Ÿš€ Features

Core Patterns

  • โœ… Domain-Driven Design (DDD) - Entity, AggregateRoot, ValueObject, DomainEvent
  • โœ… CQRS Pattern - Command/Query separation with MediatR
  • โœ… Repository & Unit of Work - Generic repository with EF Core support
  • โœ… Result Pattern - Type-safe error handling

Event-Driven Architecture

  • โœ… Event Bus - RabbitMQ and MassTransit support
  • โœ… Domain Events - In-process event handling
  • โœ… Integration Events - Cross-service communication
  • โœ… Kafka Support - High-throughput event streaming

Caching

  • โœ… In-Memory Cache - Fast local caching
  • โœ… Distributed Cache (Redis) - Scalable caching
  • โœ… Hybrid Cache - Multi-level caching strategy

Security

  • โœ… JWT Authentication - Token-based authentication
  • โœ… Permission-based Authorization - Fine-grained access control
  • โœ… Password Hashing - BCrypt integration
  • โœ… AES Encryption - Data encryption utilities
  • โœ… Rate Limiting - API throttling

Infrastructure

  • โœ… Entity Framework Core - SQL Server, PostgreSQL support
  • โœ… MongoDB - NoSQL database support
  • โœ… Elasticsearch - Full-text search
  • โœ… Azure Blob Storage - Cloud file storage
  • โœ… AWS S3 - Cloud file storage

Resilience

  • โœ… Retry Policy - Automatic retry with exponential backoff
  • โœ… Circuit Breaker - Fault tolerance
  • โœ… Timeout Policy - Request timeouts

Observability

  • โœ… Structured Logging - Serilog with Elasticsearch
  • โœ… Health Checks - Database, Redis, RabbitMQ
  • โœ… OpenTelemetry - Distributed tracing

API Features

  • โœ… Standardized API Responses - Consistent response format
  • โœ… Global Exception Handling - Centralized error handling
  • โœ… FluentValidation - Request validation
  • โœ… Swagger/OpenAPI - API documentation
  • โœ… API Versioning - Version management

Multi-Tenancy

  • โœ… Tenant Context - Tenant isolation
  • โœ… Tenant Resolver - Header/Claim-based resolution
  • โœ… Tenant Middleware - Automatic tenant detection

๐Ÿ“ฆ Installation

dotnet add package Marventa.Framework

๐Ÿ”ง Quick Start

1. Basic Setup

using Marventa.Framework.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add Marventa Framework services
builder.Services.AddMarventaFramework(builder.Configuration);
builder.Services.AddMarventaMediatR(typeof(Program).Assembly);
builder.Services.AddMarventaValidation(typeof(Program).Assembly);
builder.Services.AddMarventaLogging(builder.Configuration, "MyApp");

var app = builder.Build();

// Use Marventa middleware
app.UseMarventaFramework(app.Environment);

app.MapControllers();
app.Run();

2. Authentication & Authorization

// Add JWT authentication
builder.Services.AddMarventaJwtAuthentication(builder.Configuration);

// appsettings.json
{
  "Jwt": {
    "Secret": "your-super-secret-key-min-32-characters",
    "Issuer": "YourApp",
    "Audience": "YourApp",
    "ExpirationMinutes": 60
  }
}

3. Caching

// In-Memory Cache
builder.Services.AddMarventaCaching(builder.Configuration, CacheType.InMemory);

// Redis Cache
builder.Services.AddMarventaCaching(builder.Configuration, CacheType.Redis);

// Hybrid Cache (Memory + Redis)
builder.Services.AddMarventaCaching(builder.Configuration, CacheType.Hybrid);

// Usage
public class ProductService
{
    private readonly ICacheService _cache;

    public async Task<Product> GetProductAsync(string id)
    {
        var product = await _cache.GetAsync<Product>($"product:{id}");
        if (product == null)
        {
            product = await _repository.GetByIdAsync(id);
            await _cache.SetAsync($"product:{id}", product,
                CacheOptions.WithAbsoluteExpiration(TimeSpan.FromMinutes(30)));
        }
        return product;
    }
}

4. Event Bus (RabbitMQ)

// Configure RabbitMQ
builder.Services.AddMarventaRabbitMq(builder.Configuration);

// Define an integration event
public class OrderCreatedEvent : IntegrationEvent
{
    public Guid OrderId { get; set; }
    public decimal TotalAmount { get; set; }
}

// Publish event
public class OrderService
{
    private readonly IEventBus _eventBus;

    public async Task CreateOrderAsync(Order order)
    {
        // ... save order
        await _eventBus.PublishAsync(new OrderCreatedEvent
        {
            OrderId = order.Id,
            TotalAmount = order.Total
        });
    }
}

// Subscribe to event
public class OrderCreatedEventHandler : IIntegrationEventHandler<OrderCreatedEvent>
{
    public async Task HandleAsync(OrderCreatedEvent @event, CancellationToken cancellationToken)
    {
        // Handle event
        Console.WriteLine($"Order {@event.OrderId} created!");
    }
}

5. CQRS with MediatR

// Command
public record CreateProductCommand : ICommand<Guid>
{
    public string Name { get; init; } = string.Empty;
    public decimal Price { get; init; }
}

// Command Handler
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, Result<Guid>>
{
    private readonly IRepository<Product, Guid> _repository;
    private readonly IUnitOfWork _unitOfWork;

    public async Task<Result<Guid>> Handle(CreateProductCommand request, CancellationToken cancellationToken)
    {
        var product = new Product { Name = request.Name, Price = request.Price };
        await _repository.AddAsync(product, cancellationToken);
        await _unitOfWork.SaveChangesAsync(cancellationToken);

        return Result.Success(product.Id);
    }
}

// Query
public record GetProductQuery : IQuery<Product>
{
    public Guid Id { get; init; }
}

// Query Handler
public class GetProductQueryHandler : IRequestHandler<GetProductQuery, Result<Product>>
{
    private readonly IRepository<Product, Guid> _repository;

    public async Task<Result<Product>> Handle(GetProductQuery request, CancellationToken cancellationToken)
    {
        var product = await _repository.GetByIdAsync(request.Id, cancellationToken);
        return product != null
            ? Result.Success(product)
            : Result.Failure<Product>("Product not found", "NOT_FOUND");
    }
}

6. Database Setup

// Configure DbContext
public class AppDbContext : BaseDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options, IMediator mediator)
        : base(options, mediator) { }

    public DbSet<Product> Products => Set<Product>();
}

// Register in Program.cs
builder.Services.AddMarventaDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Register repositories
builder.Services.AddMarventaGenericRepository<Product, Guid>();

7. Entity Definition

public class Product : AuditableEntity<Guid>
{
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public string Description { get; set; } = string.Empty;

    public Product()
    {
        Id = Guid.NewGuid();
    }
}

8. API Controller

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IMediator _mediator;

    public ProductsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public async Task<IActionResult> Create(CreateProductCommand command)
    {
        var result = await _mediator.Send(command);
        var response = ApiResponseFactory.FromResult(result);
        return result.IsSuccess ? Ok(response) : BadRequest(response);
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> Get(Guid id)
    {
        var result = await _mediator.Send(new GetProductQuery { Id = id });
        var response = ApiResponseFactory.FromResult(result);
        return result.IsSuccess ? Ok(response) : NotFound(response);
    }
}

๐Ÿ” Advanced Features

Structured Logging

// Configure
builder.Services.AddMarventaLogging(builder.Configuration, "MyApp");

// Usage in services/controllers
public class OrderService
{
    private readonly ILogger<OrderService> _logger;

    public OrderService(ILogger<OrderService> logger)
    {
        _logger = logger;
    }

    public async Task CreateOrderAsync(Order order)
    {
        _logger.LogInformationStructured("Creating order for customer {CustomerId} with total {Total}",
            order.CustomerId, order.Total);

        try
        {
            // ... save order
            _logger.LogInformation("Order {OrderId} created successfully", order.Id);
        }
        catch (Exception ex)
        {
            _logger.LogErrorStructured(ex, "Failed to create order for customer {CustomerId}",
                order.CustomerId);
            throw;
        }
    }
}

Multi-Tenancy

// Configure
builder.Services.AddMarventaMultiTenancy();
app.UseMarventaMultiTenancy();

// Usage
public class ProductService
{
    private readonly ITenantContext _tenantContext;

    public async Task<List<Product>> GetProductsAsync()
    {
        var tenantId = _tenantContext.TenantId;
        // Filter by tenant
    }
}

Elasticsearch Integration

builder.Services.AddMarventaElasticsearch(builder.Configuration);

public class ProductSearchService
{
    private readonly IElasticsearchService _search;

    public async Task IndexProductAsync(Product product)
    {
        await _search.IndexDocumentAsync("products", product, product.Id.ToString());
    }

    public async Task<IEnumerable<Product>> SearchAsync(string query)
    {
        return await _search.SearchAsync<Product>("products", query);
    }
}

Health Checks

builder.Services.AddHealthChecks()
    .AddCheck<DatabaseHealthCheck>("database")
    .AddCheck<RedisHealthCheck>("redis")
    .AddCheck<RabbitMqHealthCheck>("rabbitmq");

app.MapHealthChecks("/health");

Resilience Policies

var retryPolicy = RetryPolicy.CreateRetryPolicy(3, logger);
var circuitBreaker = CircuitBreakerPolicy.CreateCircuitBreakerPolicy(5, 30, logger);
var timeout = TimeoutPolicy.CreateTimeoutPolicy(30, logger);

var result = await retryPolicy.WrapAsync(circuitBreaker).WrapAsync(timeout)
    .ExecuteAsync(async () => await _httpClient.GetAsync("https://api.example.com"));

Cloud Storage

// Azure Blob Storage
builder.Services.AddMarventaAzureStorage(builder.Configuration);

// AWS S3
builder.Services.AddMarventaAwsStorage(builder.Configuration);

// Usage
public class FileService
{
    private readonly IStorageService _storage;

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName)
    {
        return await _storage.UploadAsync(fileStream, fileName, "image/png");
    }

    public async Task<Stream> DownloadFileAsync(string fileName)
    {
        return await _storage.DownloadAsync(fileName);
    }

    public async Task<bool> DeleteFileAsync(string fileName)
    {
        return await _storage.DeleteAsync(fileName);
    }
}

MongoDB Integration

builder.Services.AddMarventaMongoDB(builder.Configuration);

public class ProductRepository
{
    private readonly IMongoDatabase _database;

    public ProductRepository(IMongoDatabase database)
    {
        _database = database;
    }

    public async Task<Product> GetByIdAsync(string id)
    {
        var collection = _database.GetCollection<Product>("products");
        return await collection.Find(p => p.Id == id).FirstOrDefaultAsync();
    }

    public async Task InsertAsync(Product product)
    {
        var collection = _database.GetCollection<Product>("products");
        await collection.InsertOneAsync(product);
    }
}

Kafka Event Streaming

builder.Services.AddMarventaKafka(builder.Configuration);

// Producer
public class OrderEventProducer
{
    private readonly IKafkaProducer _producer;

    public async Task PublishOrderCreatedAsync(Order order)
    {
        await _producer.ProduceAsync("orders-topic", new
        {
            OrderId = order.Id,
            Total = order.Total,
            CreatedAt = DateTime.UtcNow
        });
    }
}

// Consumer
public class OrderEventConsumer : BackgroundService
{
    private readonly IKafkaConsumer _consumer;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await _consumer.ConsumeAsync<OrderCreatedEvent>("orders-topic", async message =>
        {
            // Process message
            Console.WriteLine($"Order {message.OrderId} received");
        }, stoppingToken);
    }
}

MassTransit Event Bus

builder.Services.AddMarventaMassTransit(builder.Configuration, cfg =>
{
    cfg.AddConsumer<OrderCreatedEventConsumer>();
});

// Consumer
public class OrderCreatedEventConsumer : IConsumer<OrderCreatedEvent>
{
    public async Task Consume(ConsumeContext<OrderCreatedEvent> context)
    {
        var order = context.Message;
        Console.WriteLine($"Processing order {order.OrderId}");
    }
}

OpenTelemetry Tracing

builder.Services.AddMarventaOpenTelemetry(builder.Configuration, "MyApp");

// Traces are automatically collected for:
// - ASP.NET Core requests
// - HTTP client calls
// - Entity Framework queries
// - Redis operations

Rate Limiting

// Configure (100 requests per 60 seconds)
app.UseMarventaRateLimiting(requestLimit: 100, timeWindowSeconds: 60);

// Requests exceeding the limit receive HTTP 429 (Too Many Requests)

๐Ÿ“š Configuration Examples

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=MyApp;User Id=sa;Password=***;"
  },
  "Jwt": {
    "Secret": "your-super-secret-key-min-32-characters",
    "Issuer": "MyApp",
    "Audience": "MyApp",
    "ExpirationMinutes": 60
  },
  "Redis": {
    "ConnectionString": "localhost:6379",
    "InstanceName": "MyApp:"
  },
  "RabbitMQ": {
    "Host": "localhost",
    "Username": "guest",
    "Password": "guest"
  },
  "Elasticsearch": {
    "Uri": "http://localhost:9200"
  },
  "MongoDB": {
    "ConnectionString": "mongodb://localhost:27017",
    "DatabaseName": "myapp"
  },
  "Kafka": {
    "BootstrapServers": "localhost:9092",
    "GroupId": "myapp-consumer-group"
  },
  "Azure": {
    "Storage": {
      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=***;AccountKey=***",
      "ContainerName": "myapp-files"
    }
  },
  "AWS": {
    "AccessKey": "your-access-key",
    "SecretKey": "your-secret-key",
    "Region": "us-east-1",
    "BucketName": "myapp-files"
  },
  "OpenTelemetry": {
    "OtlpEndpoint": "http://localhost:4317"
  },
  "Environment": "Development"
}

Notes:

  • Environment: Used by Serilog for log enrichment
  • Logs are sent to Console + Elasticsearch (myapp-logs-yyyy-MM)
  • OpenTelemetry exports traces to OTLP endpoint (Jaeger, Zipkin, etc.)

๐Ÿงช Testing

dotnet test

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


๐Ÿ“ง Support

For issues and questions, please use GitHub Issues.


๐ŸŒŸ Show Your Support

Give a โญ๏ธ if this project helped you!

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 229 10/13/2025 5.2.0 is deprecated because it is no longer maintained.
5.1.0 277 10/5/2025 5.1.0 is deprecated because it is no longer maintained.
5.0.0 184 10/4/2025 5.0.0 is deprecated because it is no longer maintained.
4.6.0 196 10/3/2025 4.6.0 is deprecated because it is no longer maintained.
4.5.5 215 10/2/2025 4.5.5 is deprecated because it is no longer maintained.
4.5.4 210 10/2/2025 4.5.4 is deprecated because it is no longer maintained.
4.5.3 208 10/2/2025 4.5.3 is deprecated because it is no longer maintained.
4.5.2 209 10/2/2025 4.5.2 is deprecated because it is no longer maintained.
4.5.1 211 10/2/2025 4.5.1 is deprecated because it is no longer maintained.
4.5.0 212 10/2/2025 4.5.0 is deprecated because it is no longer maintained.
4.4.0 218 10/1/2025 4.4.0 is deprecated because it is no longer maintained.
4.3.0 217 10/1/2025 4.3.0 is deprecated because it is no longer maintained.
4.2.0 218 10/1/2025 4.2.0 is deprecated because it is no longer maintained.
4.1.0 210 10/1/2025 4.1.0 is deprecated because it is no longer maintained.
4.0.2 218 10/1/2025 4.0.2 is deprecated because it is no longer maintained.
4.0.1 210 10/1/2025 4.0.1 is deprecated because it is no longer maintained.
4.0.0 286 9/30/2025 4.0.0 is deprecated because it is no longer maintained.
3.5.2 219 9/30/2025 3.5.2 is deprecated because it is no longer maintained.
3.5.1 250 9/30/2025 3.5.1 is deprecated because it is no longer maintained.
3.4.1 254 9/30/2025 3.4.1 is deprecated because it is no longer maintained.
3.4.0 249 9/30/2025 3.4.0 is deprecated because it is no longer maintained.
3.3.2 261 9/30/2025 3.3.2 is deprecated because it is no longer maintained.
3.2.0 253 9/30/2025 3.2.0 is deprecated because it is no longer maintained.
3.1.0 252 9/29/2025 3.1.0 is deprecated because it is no longer maintained.
3.0.1 251 9/29/2025 3.0.1 is deprecated because it is no longer maintained.
3.0.1-preview-20250929165802 246 9/29/2025 3.0.1-preview-20250929165802 is deprecated because it is no longer maintained.
3.0.0 248 9/29/2025 3.0.0 is deprecated because it is no longer maintained.
3.0.0-preview-20250929164242 251 9/29/2025 3.0.0-preview-20250929164242 is deprecated because it is no longer maintained.
3.0.0-preview-20250929162455 248 9/29/2025 3.0.0-preview-20250929162455 is deprecated because it is no longer maintained.
2.12.0-preview-20250929161039 242 9/29/2025 2.12.0-preview-20250929161039 is deprecated because it is no longer maintained.
2.11.0 253 9/29/2025 2.11.0 is deprecated because it is no longer maintained.
2.10.0 253 9/29/2025 2.10.0 is deprecated because it is no longer maintained.
2.9.0 247 9/29/2025 2.9.0 is deprecated because it is no longer maintained.
2.8.0 249 9/29/2025 2.8.0 is deprecated because it is no longer maintained.
2.7.0 260 9/29/2025 2.7.0 is deprecated because it is no longer maintained.
2.6.0 254 9/28/2025 2.6.0 is deprecated because it is no longer maintained.
2.5.0 260 9/28/2025 2.5.0 is deprecated because it is no longer maintained.
2.4.0 252 9/28/2025 2.4.0 is deprecated because it is no longer maintained.
2.3.0 253 9/28/2025 2.3.0 is deprecated because it is no longer maintained.
2.2.0 255 9/28/2025 2.2.0 is deprecated because it is no longer maintained.
2.1.0 253 9/26/2025 2.1.0 is deprecated because it is no longer maintained.
2.0.9 257 9/26/2025 2.0.9 is deprecated because it is no longer maintained.
2.0.5 250 9/25/2025 2.0.5 is deprecated because it is no longer maintained.
2.0.4 256 9/25/2025 2.0.4 is deprecated because it is no longer maintained.
2.0.3 261 9/25/2025 2.0.3 is deprecated because it is no longer maintained.
2.0.1 257 9/25/2025 2.0.1 is deprecated because it is no longer maintained.
2.0.0 258 9/25/2025 2.0.0 is deprecated because it is no longer maintained.
1.1.2 334 9/24/2025 1.1.2 is deprecated because it is no longer maintained.
1.1.1 335 9/24/2025 1.1.1 is deprecated because it is no longer maintained.
1.1.0 253 9/24/2025 1.1.0 is deprecated because it is no longer maintained.
1.0.0 258 9/24/2025 1.0.0 is deprecated because it is no longer maintained.