OnlineMenu.MultiTenancy.EntityFrameworkCore 1.0.0

dotnet add package OnlineMenu.MultiTenancy.EntityFrameworkCore --version 1.0.0
                    
NuGet\Install-Package OnlineMenu.MultiTenancy.EntityFrameworkCore -Version 1.0.0
                    
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="OnlineMenu.MultiTenancy.EntityFrameworkCore" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OnlineMenu.MultiTenancy.EntityFrameworkCore" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="OnlineMenu.MultiTenancy.EntityFrameworkCore" />
                    
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 OnlineMenu.MultiTenancy.EntityFrameworkCore --version 1.0.0
                    
#r "nuget: OnlineMenu.MultiTenancy.EntityFrameworkCore, 1.0.0"
                    
#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 OnlineMenu.MultiTenancy.EntityFrameworkCore@1.0.0
                    
#: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=OnlineMenu.MultiTenancy.EntityFrameworkCore&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=OnlineMenu.MultiTenancy.EntityFrameworkCore&version=1.0.0
                    
Install as a Cake Tool

OnlineMenu.Foundation

Build Status NuGet License: MIT

Foundation packages for building multi-tenant SaaS applications with .NET and Entity Framework Core. These packages provide the essential building blocks for Domain-Driven Design, security, and multi-tenancy.

๐Ÿ“ฆ Packages

Package Version Description
OnlineMenu.DomainCore NuGet Domain primitives, base entities, aggregate roots, and domain events
OnlineMenu.Security NuGet Security claims, roles, and ClaimsPrincipal extensions
OnlineMenu.MultiTenancy.EntityFrameworkCore NuGet Multi-tenant data isolation for EF Core

๐Ÿš€ Quick Start

Installation

# Install all packages
dotnet add package OnlineMenu.DomainCore
dotnet add package OnlineMenu.Security
dotnet add package OnlineMenu.MultiTenancy.EntityFrameworkCore

Basic Usage

1. Domain Entities
using OnlineMenu.DomainCore.Entities;

// Simple entity
public class Product : BaseEntity
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Multi-tenant entity
public class Order : BaseTenantEntity
{
    public Guid ProductId { get; set; }
    public int Quantity { get; set; }
    public decimal TotalPrice { get; set; }
}
2. Security Claims
using OnlineMenu.Security.Claims;

public class MyController : ControllerBase
{
    [Authorize]
    public IActionResult GetUserInfo()
    {
        var tenantId = User.GetTenantId();
        var email = User.GetEmail();
        var isSuperUser = User.IsSuperUser();

        return Ok(new { tenantId, email, isSuperUser });
    }
}
3. Multi-Tenancy Setup
using OnlineMenu.MultiTenancy.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Register multi-tenancy services
builder.Services.AddMultiTenancy();

// Configure your DbContext to filter by tenant
builder.Services.AddDbContext<MyDbContext>(options =>
{
    options.UseNpgsql(connectionString);
});

๐Ÿ“– Documentation

OnlineMenu.DomainCore

Provides base classes for Domain-Driven Design:

  • BaseEntity: Base class with Id, ExternalId, and audit fields
  • BaseTenantEntity: Base class for tenant-scoped entities
  • IAggregateRoot: Marker interface for aggregate roots
  • HasDomainEventsBase: Base class for entities that raise domain events
  • DomainEventBase: Base class for domain events

Example:

public class TodoItem : BaseTenantEntity
{
    public string Title { get; private set; }
    public bool IsCompleted { get; private set; }

    public TodoItem(string title, Guid tenantId, Guid userId)
    {
        Title = title;
        SetTenant(tenantId);
        SetUser(userId);
    }

    public void MarkComplete()
    {
        IsCompleted = true;
        UpdateTimestamp();
    }
}

OnlineMenu.Security

Provides security-related utilities:

  • OnlineMenuClaimTypes: Standard claim type constants
  • OnlineMenuRoles: Standard role constants
  • ClaimsPrincipalExtensions: Extension methods for ClaimsPrincipal

Available Extension Methods:

// Identity claims
Guid? tenantId = user.GetTenantId();
string? userId = user.GetSubjectId();
string? email = user.GetEmail();
string? name = user.GetName();

// Role checks
bool isSuperUser = user.IsSuperUser();
bool isAdmin = user.IsAdmin();
bool canManageUsers = user.CanManageUsers();
bool canViewUsers = user.CanViewUsers();

Standard Roles:

  • SuperUser - Full system access
  • Admin - Tenant administrator
  • ManageUsers - Can manage users
  • ViewUsers - Can view users

OnlineMenu.MultiTenancy.EntityFrameworkCore

Provides multi-tenancy support for EF Core:

  • Tenant: Core tenant entity with auth configuration
  • TenantStatus: Enum for tenant states (Enabled/Disabled)
  • ICurrentTenantService: Service to access current tenant context
  • CurrentTenantService: Implementation that extracts tenant from HTTP context

Setup:

// Program.cs
builder.Services.AddMultiTenancy();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.Authority = "https://your-identity-provider.com";
    });

// DbContext.cs
public class MyDbContext : DbContext
{
    private readonly ICurrentTenantService _currentTenantService;

    public MyDbContext(
        DbContextOptions<MyDbContext> options,
        ICurrentTenantService currentTenantService) : base(options)
    {
        _currentTenantService = currentTenantService;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply global tenant filter
        modelBuilder.Entity<Order>().HasQueryFilter(e =>
            _currentTenantService.TenantId == null ||
            e.TenantId == _currentTenantService.TenantId);
    }
}

Tenant Entity Features:

var tenant = new Tenant("Acme Corp", TenantStatus.Enabled);

// Update basic info
tenant.Update("Acme Corporation", TenantStatus.Enabled,
    logoUrl: "https://example.com/logo.png",
    primaryColor: "#FF5733");

// Configure authentication
tenant.UpdateAuthConfiguration(
    primaryAuthMethod: 1, // Phone OTP
    allowPhoneAuth: true,
    allowEmailAuth: true,
    otpCodeLength: 6,
    otpExpiryMinutes: 5,
    smsProvider: "Twilio",
    requireSmsVerification: true
);

๐Ÿ—๏ธ Architecture

These packages follow these principles:

  • Domain-Driven Design: Clear separation between domain, infrastructure, and application layers
  • Dependency Inversion: Depend on abstractions, not concrete implementations
  • Single Responsibility: Each package has a focused purpose
  • Multi-Tenancy First: Built-in support for SaaS applications
  • Security First: JWT-based authentication with role-based authorization

๐Ÿ”ง Advanced Usage

Domain Events

public class OrderPlacedEvent : DomainEventBase
{
    public Guid OrderId { get; }
    public decimal TotalAmount { get; }

    public OrderPlacedEvent(Guid orderId, decimal totalAmount)
    {
        OrderId = orderId;
        TotalAmount = totalAmount;
    }
}

public class Order : BaseTenantEntity
{
    public void Place()
    {
        // Business logic...
        RegisterDomainEvent(new OrderPlacedEvent(ExternalId, TotalPrice));
    }
}

Custom Authorization

[Authorize]
public class AdminController : ControllerBase
{
    [HttpGet]
    public IActionResult GetDashboard()
    {
        if (!User.IsAdmin() && !User.IsSuperUser())
            return Forbid();

        // Admin logic...
        return Ok();
    }
}

Tenant Isolation

public class OrderService
{
    private readonly ICurrentTenantService _tenantService;
    private readonly MyDbContext _dbContext;

    public async Task<Order> CreateOrderAsync(CreateOrderDto dto)
    {
        var order = new Order
        {
            // ... other properties
        };

        // Automatically set tenant
        order.SetTenant(_tenantService.TenantId!.Value);
        order.SetUser(_tenantService.UserId!.Value);

        _dbContext.Orders.Add(order);
        await _dbContext.SaveChangesAsync();

        return order;
    }
}

๐Ÿงช Testing

All packages include comprehensive unit tests:

# Run all tests
dotnet test

# Run with coverage
dotnet test /p:CollectCoverage=true /p:CoverageReportFormat=opencover

๐Ÿค Contributing

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

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“ License

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

๐Ÿ’ฌ Support

๐Ÿ™ Acknowledgments

  • Built with .NET 8
  • Inspired by Domain-Driven Design principles
  • Part of the OnlineMenu ecosystem

Made with โค๏ธ by the OnlineMenu team

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 was computed.  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
1.0.0 74 12/28/2025