ICommandor 1.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package ICommandor --version 1.0.3
                    
NuGet\Install-Package ICommandor -Version 1.0.3
                    
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="ICommandor" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ICommandor" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="ICommandor" />
                    
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 ICommandor --version 1.0.3
                    
#r "nuget: ICommandor, 1.0.3"
                    
#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 ICommandor@1.0.3
                    
#: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=ICommandor&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=ICommandor&version=1.0.3
                    
Install as a Cake Tool

Commandor

Commandor - MediatR uchun zamonaviy, yuqori samaradorlikka ega alternative. ActualLab.Fusion va MediatR'dan ilhomlangan, Source Generator va Automatic Caching bilan.

.NET Tests License

โœจ Asosiy Xususiyatlar

  • ๐Ÿš€ Zero Boilerplate - Handler'larni yozish shart emas (Source Generator)
  • โšก Auto Caching - Query'lar avtomatik cache'lanadi (3-5x tezroq)
  • ๐Ÿ”ฅ Fusion Pattern - Dependency tracking va transitive invalidation
  • ๐Ÿ’พ GC-free Cache - LiteAPI.Cache (Rust-backed, ultra-fast)
  • ๐ŸŽฏ Type-Safe - To'liq compile-time xavfsizlik
  • ๐Ÿ”„ Command/Query Separation - [CommandHandler] va [QueryHandler]
  • ๐Ÿงช Production Ready - 29/29 test o'tgan, ishonchli

๐Ÿš€ Quick Start

1. O'rnatish

dotnet add package Commandor

2. Command va Query yaratish

using Commandor;

// Commands (Write operations - cache invalidation)
public record CreateProductCommand(string Name, decimal Price) : IRequest<Product>;
public record UpdatePriceCommand(int Id, decimal Price) : IRequest;

// Queries (Read operations - auto caching)
public record GetProductByIdQuery(int Id) : IRequest<Product?>;

3. Service interface - Attribute bilan

public interface IProductService : ICommandorService
{
    [CommandHandler]  // โœจ Handler avtomatik yaratiladi!
    Task<Product> CreateProduct(CreateProductCommand cmd, CancellationToken ct = default);
    
    [CommandHandler]  // โœจ Cache'ni invalidate qiladi
    Task UpdatePrice(UpdatePriceCommand cmd, CancellationToken ct = default);
    
    [QueryHandler]    // ๐Ÿ”ฅ Natija avtomatik cache'lanadi!
    Task<Product?> GetProductById(GetProductByIdQuery query, CancellationToken ct = default);
}

4. Service implementation - Faqat business logic

public class ProductService : IProductService
{
    private readonly List<Product> _products = new();
    private readonly IComputedCache _cache;
    
    public ProductService(IComputedCache cache) => _cache = cache;
    
    public Task<Product> CreateProduct(CreateProductCommand cmd, CancellationToken ct)
    {
        var product = new Product 
        { 
            Id = Random.Shared.Next(1000, 9999),
            Name = cmd.Name, 
            Price = cmd.Price 
        };
        _products.Add(product);
        return Task.FromResult(product);
    }
    
    public Task UpdatePrice(UpdatePriceCommand cmd, CancellationToken ct)
    {
        var product = _products.First(p => p.Id == cmd.Id);
        product.Price = cmd.Price;
        
        // Cache'ni qo'lda invalidate qilish (GetProductById cache key)
        var cacheKey = CacheKeyBuilder.Build(
            typeof(IProductService),
            nameof(GetProductById),
            new GetProductByIdQuery(cmd.Id));
        _cache.Remove(cacheKey);
        
        return Task.CompletedTask;
    }
    
    public Task<Product?> GetProductById(GetProductByIdQuery query, CancellationToken ct)
    {
        // Bu metod avtomatik cache'lanadi! โšก
        var product = _products.FirstOrDefault(p => p.Id == query.Id);
        return Task.FromResult(product);
    }
}

5. DI Setup

var services = new ServiceCollection();

// Commandor qo'shish
services.AddCommandor();

// Service va auto-generated handler'larni ro'yxatga olish
services.AddCommandorService<IProductService, ProductService>();

var serviceProvider = services.BuildServiceProvider();

6. Ishlatish

var commandor = serviceProvider.GetRequiredService<ICommandor>();

// 1. Mahsulot yaratish
var product = await commandor.SendAsync(
    new CreateProductCommand("iPhone 15 Pro", 15000000));

// 2. Birinchi query - DB'dan (~1.5ms)
var p1 = await commandor.SendAsync(new GetProductByIdQuery(product.Id));

// 3. Ikkinchi query - CACHE'dan (~0.3ms) โšกโšกโšก 5x TEZROQ!
var p2 = await commandor.SendAsync(new GetProductByIdQuery(product.Id));

// 4. Narxni yangilash - cache invalidate
await commandor.SendAsync(new UpdatePriceCommand(product.Id, 14500000));

// 5. Keyingi query - yangi ma'lumot DB'dan
var p3 = await commandor.SendAsync(new GetProductByIdQuery(product.Id));

๐Ÿ“Š Performance

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Birinchi Query (DB):      ~1.5-2.0ms      โ”‚
โ”‚  Cached Query:             ~0.3-0.6ms      โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚  Tezlashish:               3-5x            โ”‚
โ”‚  GC Pressure:              ZERO            โ”‚
โ”‚  Memory:                   Ultra-efficient  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐ŸŽฏ Command vs Query

Commands - Write Operations

[CommandHandler]  // โŒ Cache'lanmaydi
Task<Product> CreateProduct(CreateProductCommand cmd);

[CommandHandler]  // โšก Cache'ni invalidate qiladi  
Task UpdatePrice(UpdatePriceCommand cmd);

Xususiyatlari:

  • Ma'lumotlarni o'zgartiradi (Create, Update, Delete)
  • Cache'lanmaydi
  • Tegishli Query'larni invalidate qiladi

Queries - Read Operations

[QueryHandler]  // โœ… Avtomatik cache'lanadi
Task<Product?> GetProductById(GetProductByIdQuery query);

[QueryHandler]  // โœ… Avtomatik cache'lanadi
Task<List<Product>> GetAllProducts(GetAllProductsQuery query);

Xususiyatlari:

  • Faqat ma'lumot o'qiydi (Read-only)
  • Avtomatik cache'lanadi
  • Dependency tracking bilan
  • Transitive invalidation

๐Ÿ”ฅ Fusion Pattern - Dependency Tracking

Commandor ActualLab.Fusion'dan ilhomlangan dependency tracking mexanizmini ishlatadi:

// A โ†’ B bog'liqligi
var productList = await commandor.SendAsync(new GetProductListQuery());
// Ichida GetProductById chaqirilgan

// GetProductById invalidate bo'lsa
await commandor.SendAsync(new UpdatePriceCommand(1, 15000));

// GetProductList ham invalidate bo'ladi! (Transitive)
var updatedList = await commandor.SendAsync(new GetProductListQuery());

Computed Values

Har bir cached natija Computed<T> sifatida saqlanadi:

public interface IComputed<T>
{
    T Value { get; }                    // Cache'langan qiymat
    long Version { get; }               // Versiya (invalidation tracking)
    ConsistencyState State { get; }     // Consistent, Computing, Invalidated
    bool IsConsistent();                // Cache hali fresh?
    void Invalidate();                  // Cache'ni bekor qilish
    Task WhenInvalidated();             // Invalidation kutish
}

๐Ÿ’พ LiteAPI.Cache - GC-free Caching

Commandor LiteAPI.Cache 1.1.0 dan foydalanadi:

Afzalliklar

  • โšก Ultra-fast - Rust-backed native implementation
  • ๐Ÿง  GC-free - .NET garbage collector'ga ta'sir qilmaydi
  • ๐Ÿ”’ Thread-safe - Concurrent access safe
  • ๐Ÿ’พ Cross-platform - Windows, Linux, macOS
  • ๐Ÿš€ Production-ready - Battle-tested

Cache Key Format

ServiceType.MethodName(arg1, arg2, ...)

Misollar:
- ProductService.GetProductById(1)
- ProductService.GetAllProducts()
- UserService.GetUserByEmail("john@example.com")

๐Ÿง  Query Caching

  • [QueryHandler] bilan belgilangan har bir metod uchun generator avtomatik IRequestHandler<TRequest, TResponse> yaratadi va natijani IComputedCache ga yozadi.
  • Cache key CacheKeyBuilder.Build(typeof(Service), MethodName, request) formulasi asosida hisoblanadi; request JSON'ga serializatsiya qilinadi, shuning uchun record/immutable turlar eng qulay variant.
  • services.AddCommandor() chaqirilganda LiteAPI.Cache ishlatiladi; agar native kutubxona topilmasa, avtomatik CommandorMemoryCache ga fallback qiladi. Xohlasangiz IComputedCache ni o'zingiz override qilishingiz mumkin.
  • TTL (CacheTtlSeconds) property hozircha rezerv qilingan bo'lib, invalidate jarayoni qo'lda bajariladi. Service implementatsiyasiga IComputedCache ni inject qiling va tegishli key ni Remove qiling (yuqoridagi misolda ko'rsatilganidek).
  • Cache faqat bir xil request obyekti uchun ishlaydi; request parametrlarini o'zgartirish boshqa cache key beradi va handler qayta bajariladi.

๐Ÿ”ง Qo'shimcha Ma'lumotlar

  • Commandor paketini loyihangizga qo'shgandan so'ng, Visual Studio yoki dotnet build yordamida loyihani qayta qurishingiz kerak. Bu, generatorning source code'mizga yaratilishini ta'minlaydi.
  • IntelliSense va kodni to'ldirish funktsiyalari uchun Visual Studio'da yechimingizni yangilang.

โ“ FAQ

Methodlarni virtual qilish shartmi?

Yoสปq. Commandor generatori interface deklaratsiyasini oสปqiydi va [CommandHandler]/[QueryHandler] atributlari tushirilgan metodlar asosida ichki handlerlarni yaratadi. Implementatsiya sinfida metodlarni virtual qilish talab qilinmaydi; oddiy Task/Task<T> signaturasi va CancellationToken parametri yetarli.

Query caching nima uchun ishlamayapti?

  • Commandor paketini o'rnatganingizga ishonch hosil qiling.
  • DI'da albatta services.AddCommandor() va tegishli services.AddCommandorService<...>() chaqiring โ€“ shu paytda mediator va IComputedCache registratsiya qilinadi.
  • Request/response turlari System.Text.Json tomonidan serializatsiya qilina olishi kerak, chunki cache key va natija JSON orqali saqlanadi.
  • Default LiteAPI.Cache native kutubxonasini topa olmasa, fallback sifatida CommandorMemoryCache ishlaydi. Zarurat bo'lsa, o'zingizning IComputedCache implementatsiyangizni registratsiya qiling yoki diagnostika uchun log qo'shing.
  • Cache ni qo'lda invalidate qilish uchun service'ga IComputedCache inject qiling va CacheKeyBuilder orqali kerakli key'ni topib, Remove qiling.
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
1.1.0 1,593 12/30/2025
1.0.6 2,308 12/22/2025
1.0.5 2,300 12/22/2025
1.0.4 2,317 12/22/2025
1.0.3 2,322 12/22/2025
1.0.2 2,327 12/22/2025
1.0.1 2,857 12/15/2025
1.0.0 4,304 11/18/2025

test