AlmaalimCommonLib 1.0.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package AlmaalimCommonLib --version 1.0.0
                    
NuGet\Install-Package AlmaalimCommonLib -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="AlmaalimCommonLib" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AlmaalimCommonLib" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="AlmaalimCommonLib" />
                    
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 AlmaalimCommonLib --version 1.0.0
                    
#r "nuget: AlmaalimCommonLib, 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 AlmaalimCommonLib@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=AlmaalimCommonLib&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=AlmaalimCommonLib&version=1.0.0
                    
Install as a Cake Tool

AlmaalimCommonLib

A common library providing reusable infrastructure for ASP.NET Core applications.

Installation

  1. Add this project as a reference to your ASP.NET Core project
  2. Configure your appsettings.json with required configuration

Quick Start

using AlmaalimCommonLib.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add all services in one line
builder.Services.AddAlmaalimAll(builder.Configuration);

// Or just infrastructure services
builder.Services.AddAlmaalimServices(builder.Configuration);

// Add authentication separately if needed
builder.Services.AddAlmaalimAuthentication(builder.Configuration);

var app = builder.Build();

// Use middleware
app.UseAlmaalimMiddleware();

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

Option 2: Individual Extensions

using AlmaalimCommonLib.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Infrastructure services
builder.Services.AddInfrastructureServices(builder.Configuration);

// Or individual
builder.Services.AddDbContextConfiguration(builder.Configuration);
builder.Services.AddIdentityConfiguration();
builder.Services.AddFileStorageConfiguration(builder.Configuration);
builder.Services.AddRepositoryConfiguration();

// Authentication
builder.Services.AddDefaultAuthentication(builder.Configuration);

// API Versioning
builder.Services.AddApiVersioning();

var app = builder.Build();

app.UseGlobalExceptionHandler();
app.UseRateLimiter();

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

Configuration

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.;Database=YourDb;Trusted_Connection=True;TrustServerCertificate=True"
  },
  "Storage": {
    "UploadsPath": "uploads"
  },
  "TokenSettings": {
    "Key": "your-secret-key-min-32-characters-long",
    "Issuer": "YourIssuer",
    "Audience": "YourAudience",
    "ExpiryInMinutes": 60,
    "RefreshTokeExpireInMinutes": 3600
  },
  "Email": {
    "Host": "smtp.example.com",
    "Port": 587,
    "UserName": "noreply@example.com",
    "Password": "your-password",
    "From": "noreply@example.com"
  }
}

Dependency Injection Extensions

Facade Methods

Method Description
AddAlmaalimServices(configuration) DbContext + Identity + FileStorage + Repositories
AddAlmaalimAll(configuration) Infrastructure + JWT Auth + API Versioning
AddAlmaalimAuthentication(configuration) JWT Bearer authentication
UseAlmaalimMiddleware(app) Global exception handler + Rate limiting

Individual Extensions

Method Description
AddInfrastructureServices(configuration) Calls all infrastructure extensions
AddDbContextConfiguration(configuration, scheme, useNetTopologySuite, registerAuditInterceptor, registerSoftDeleteInterceptor) EF Core DbContext with SQL Server
AddIdentityConfiguration() ASP.NET Core Identity
AddFileStorageConfiguration(configuration) Local file storage
AddRepositoryConfiguration(registerDefaultDataSeeder) Generic Repository + specific repositories
AddDefaultAuthentication(configuration) JWT Bearer authentication
AddApiVersioning() API versioning (URL/header/media)
AddOpenApiServices(hostEnvironment) OpenAPI (Development only)

Middleware Extensions

Method Description
UseGlobalExceptionHandler(app) Global exception handler
UseRateLimiter(app, options) Rate limiting (defaults: 100 req/15min)
UseOpenApiExplorer(builder, environment) OpenAPI endpoint (Development only)

Database Context

// Your project's DbContext
public class ApplicationDbContext : AlmaalimCommonLib.Persistence.ApplicationDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options) { }
}

Required Entities

// Entities/DefaultUser.cs
public class DefaultUser : AlmaalimCommonLib.Entities.Common.DefaultUser { }

// Entities/ApplicationRole.cs
public class ApplicationRole : AlmaalimCommonLib.Entities.Common.ApplicationRole { }

// Entities/ApplicationUserRole.cs
public class ApplicationUserRole : AlmaalimCommonLib.Entities.Common.ApplicationUserRole { }

Required Interceptors

// Must be registered in DI
services.AddScoped<AuditableEntityInterceptor>();
services.AddScoped<SoftDeleteInterceptor>();

// Implement in your project (or inherit from library if available)
public class AuditableEntityInterceptor : ...
public class SoftDeleteInterceptor : ...

Controllers

APIBaseController

Base controller with JWT authorization and API versioning:

public class MyController : AlmaalimCommonLib.Controllers.APIBaseController
{
    [HttpGet]
    public IActionResult Get() => Ok("Hello");
}

APICrudController

Generic CRUD controller - extend and provide types:

public class ProductsController : AlmaalimCommonLib.Controllers.APICrudController<
    Product,           // Entity
    ProductResponse,   // Response DTO
    CreateProduct,     // Create Request DTO
    EditProduct,       // Edit Request DTO
    ListRequest        // List Request DTO
>
{
    public ProductsController(
        ICrudService<Product, ProductResponse, CreateProduct, EditProduct, ListRequest> service
    ) : base(service) { }
}

DTOs

Required Interfaces

public class CreateProduct : AlmaalimCommonLib.DTOs.Common.ICreateRequest
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class EditProduct : AlmaalimCommonLib.DTOs.Common.IEditRequest
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class ListRequest : AlmaalimCommonLib.DTOs.Common.IListRequest
{
    public string? SearchTerm { get; set; }
    public string? SortBy { get; set; }
    public bool SortDescending { get; set; }
    public int Page { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}

Services

ICrudService

Generic CRUD service with pagination, search, and validation:

public class ProductService : AlmaalimCommonLib.Services.CrudService<
    Product, ProductResponse, CreateProduct, EditProduct, ListRequest
>
{
    public ProductService(IRepository<Product> repository) : base(repository) { }

    protected override Product MapToEntity(CreateProduct request) => new Product
    {
        Id = Guid.NewGuid(),
        Name = request.Name,
        Price = request.Price,
        CreatedAt = DateTime.UtcNow
    };

    protected override ProductResponse MapToResponse(Product entity) => new ProductResponse
    {
        Id = entity.Id,
        Name = entity.Name,
        Price = entity.Price,
        CreatedAt = entity.CreatedAt
    };

    protected override void UpdateEntity(Product entity, EditProduct request)
    {
        entity.Name = request.Name;
        entity.Price = request.Price;
    }

    protected override IQueryable<Product> ApplySearchFilter(
        IQueryable<Product> query,
        string searchTerm
    ) => query.Where(p => p.Name.Contains(searchTerm));
}

IIdentityService

Authentication and user management:

var result = await identityService.LoginUserAsync(username, password, ipAddress);
var result = await identityService.RegisterUserAsync(username, password, "User");
var result = await identityService.RefreshUserRefreshToken(refreshToken, ipAddress);
var result = await identityService.RevokeRefreshToken(username, token, ipAddress);

Repositories

IRepository<T>

Generic repository with soft delete support:

// Query (filters soft-deleted)
var entity = await repository.GetByIdAsync(id);

// Query including soft-deleted
var all = await repository.QueryWithDeleted().ToListAsync();

// Query soft-deleted only
var deleted = await repository.QueryDeletedOnly().ToListAsync();

// Hard delete
await repository.ForceDeleteAsync(id);

// Restore soft-deleted
await repository.RestoreAsync(id);

Custom Repositories

public interface IProductRepository : AlmaalimCommonLib.Contracts.IRepository<Product>
{
    Task<IReadOnlyList<Product>> GetByCategoryAsync(string category);
}

public class ProductRepository : AlmaalimCommonLib.Repositories.Repository<Product>,
    IProductRepository
{
    public ProductRepository(ApplicationDbContext context) : base(context) { }

    public async Task<IReadOnlyList<Product>> GetByCategoryAsync(string category)
    {
        return await Query().Where(p => p.Category == category).ToListAsync();
    }
}

Extension Methods

Soft Delete

// Include soft-deleted in query
var all = await context.Products.IncludeDeleted().ToListAsync();

// Filter to deleted only
var deleted = await context.Products.WhereDeleted().ToListAsync();

// Filter to active only
var active = await context.Products.WhereNotDeleted().ToListAsync();

// In code
entity.Restore();
entity.SoftDelete(userId);

HttpContext

var userId = context.GetUserId();

OneOf to API Response

// Convert OneOf results to standardized API responses
return result.ToApiResponse();

File Storage

// Interface
public interface IFileStorage
{
    Task<string> SaveAsync(Stream file, string fileName);
    Task<Stream> LoadAsync(string path);
    Task DeleteAsync(string path);
    string GetFullPath(string path);
}

// Usage
var path = await fileStorage.SaveAsync(stream, "file.txt");

Events

// Publish
await eventBus.PublishAsync(new OrderCreatedEvent(order));

// Subscribe
public class OrderEventHandler : AlmaalimCommonLib.Contracts.IEventHandler<OrderCreatedEvent>
{
    public Task Handle(OrderCreatedEvent @event) { ... }
}

Required Project Types

Your project must define:

  • DefaultUser - inherits from library's DefaultUser
  • ApplicationRole - inherits from library's ApplicationRole
  • ApplicationUserRole - inherits from library's ApplicationUserRole
  • ApplicationDbContext - inherits from library's ApplicationDbContext
  • AuditableEntityInterceptor - implements audit logic
  • SoftDeleteInterceptor - implements soft delete logic
  • Entity classes implementing IEntity<Guid>

Packages

The library uses these packages:

  • Microsoft.EntityFrameworkCore + SqlServer
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore
  • Microsoft.AspNetCore.Authentication.JwtBearer
  • Asp.Versioning.Mvc
  • OneOf
  • Riok.Mapperly
  • System.IdentityModel.Tokens.Jwt
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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