MDev.Dotnet.Azure.ContainerApps
1.14.0
dotnet add package MDev.Dotnet.Azure.ContainerApps --version 1.14.0
NuGet\Install-Package MDev.Dotnet.Azure.ContainerApps -Version 1.14.0
<PackageReference Include="MDev.Dotnet.Azure.ContainerApps" Version="1.14.0" />
<PackageVersion Include="MDev.Dotnet.Azure.ContainerApps" Version="1.14.0" />
<PackageReference Include="MDev.Dotnet.Azure.ContainerApps" />
paket add MDev.Dotnet.Azure.ContainerApps --version 1.14.0
#r "nuget: MDev.Dotnet.Azure.ContainerApps, 1.14.0"
#:package MDev.Dotnet.Azure.ContainerApps@1.14.0
#addin nuget:?package=MDev.Dotnet.Azure.ContainerApps&version=1.14.0
#tool nuget:?package=MDev.Dotnet.Azure.ContainerApps&version=1.14.0
MDev.Dotnet
Welcome to MDev.Dotnet - a collection of production-ready helpers and tools designed to accelerate .NET web application development and simplify cloud service integration. This repository provides battle-tested libraries that streamline common development tasks and Azure PaaS service configurations.
Table of Contents
Overview
This repository contains four main packages that help you build robust .NET applications with Azure integration:
- AspNetCore helpers for standard web API configuration
- Container Apps helpers for OpenTelemetry, authentication, and async operations
- CosmosDb helpers for Entity Framework Core integration
- Storage Account helpers for blob and queue operations
Each package follows consistent patterns and integrates seamlessly with the .NET dependency injection system.
Quick Start
Install the NuGet package you need:
dotnet add package MDev.Dotnet.AspNetCore dotnet add package MDev.Dotnet.Azure.ContainerApps dotnet add package MDev.Dotnet.Azure.CosmosDb dotnet add package MDev.Dotnet.Azure.StorageAccountConfigure your services in
Program.csAdd required configuration sections to
appsettings.jsonStart using the helpers in your application
Packages
MDev.Dotnet.AspNetCore
🎯 Highlight
Streamline ASP.NET Core web API configuration with pre-configured controllers, routing, API versioning, and configuration management. This package eliminates boilerplate code and enforces best practices for web API development.
Key Features:
- ✅ Simplified controller registration with built-in logging for 400 errors
- ✅ Automatic API versioning support
- ✅ Configuration binding with type safety
- ✅ Lowercase URL routing
- ✅ OpenAPI/Swagger configuration
- ✅ Route prefix middleware
- ✅ Synchronous IO support when needed
📚 Explain
This package provides extension methods that wrap common ASP.NET Core configurations into single-line registrations. It helps you:
- Controller Registration - Registers controllers with automatic model validation logging
- Configuration Management - Binds configuration sections to strongly-typed objects
- API Versioning - Adds versioning support to your APIs
- OpenAPI Support - Configures OpenAPI documentation with customizable options
- Route Prefixing - Adds global route prefixes to your API endpoints
Main Extension Methods:
RegisterControllers<T>()- Registers MVC controllers with logging and versioningRegisterConfiguration()- Loads appsettings.json with environment-specific overridesBindConfiguration<T>()- Binds configuration sections to POCOsRegisterOpenApi()- Configures OpenAPI/Swagger documentationUseRoutePrefix()- Adds a route prefix to all endpoints
🔗 Resources
- NuGet Package:
- Wiki Documentation: MDev.Dotnet Wiki
- Source Code: src/MDev.Dotnet.AspNetCore
⚙️ Operation
Installation
dotnet add package MDev.Dotnet.AspNetCore
Basic Setup in Program.cs
using MDev.Dotnet.AspNetCore.Apis.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register configuration
builder.RegisterConfiguration();
// Register controllers with API versioning
builder.RegisterControllers<Program>();
// Register OpenAPI
builder.RegisterOpenApi();
var app = builder.Build();
// Add route prefix (optional)
app.UseRoutePrefix("api");
app.MapControllers();
app.MapOpenApi();
app.Run();
Configuration Binding Example
// Define your settings class
public class MyAppSettings
{
public string ApiKey { get; set; }
public int Timeout { get; set; }
}
// In Program.cs
builder.BindConfiguration<MyAppSettings>(out var settings, "MyAppSettings");
// Or inject via IOptions<T>
builder.BindConfiguration<MyAppSettings>("MyAppSettings");
// In your service
public class MyService
{
private readonly MyAppSettings _settings;
public MyService(IOptions<MyAppSettings> settings)
{
_settings = settings.Value;
}
}
appsettings.json Example
{
"MyAppSettings": {
"ApiKey": "your-api-key",
"Timeout": 30
}
}
Advanced Controller Registration
// With synchronous IO support
builder.RegisterControllers<Program>(
allowSynchronousIO: true,
mvcOptions: options => {
// Add custom MVC options
options.MaxModelValidationErrors = 50;
}
);
OpenAPI Configuration
// Force HTTPS and hide server URLs
builder.RegisterOpenApi(
forceHttpsServers: true,
includeServerUrls: false
);
MDev.Dotnet.Azure.ContainerApps
🎯 Highlight
Supercharge your Azure Container Apps with integrated OpenTelemetry, authentication helpers, and Dapr-based async operations. This package simplifies container app configuration and monitoring.
Key Features:
- ✅ OpenTelemetry integration with Azure Monitor or custom OTLP endpoints
- ✅ Container Apps authentication helpers
- ✅ Dapr pub/sub async operation handlers
- ✅ Built-in metrics, tracing, and logging
- ✅ Configurable status code handling
- ✅ Dapr API token validation
📚 Explain
This package builds on top of MDev.Dotnet.AspNetCore and adds Azure Container Apps-specific functionality:
- OpenTelemetry Configuration - Automatic setup for Azure Monitor or Dynatrace with customizable metrics
- Authentication Helpers - Easy access to Container Apps authentication context
- Async Operations - Base controller for handling Dapr pub/sub messages
- Dapr Integration - Attribute-based API token validation
Main Components:
RegisterOpenTelemetry()- Configures OpenTelemetry with Azure Monitor or OTLPDaprHandlerController- Base controller for Dapr pub/sub handlersIAsyncOperationRequestMessageHandler- Interface for async operation handlersRequireDaprApiTokenAttribute- Validates Dapr API tokensMsClientPrincipal- Access Container Apps authentication context
🔗 Resources
- NuGet Package:
- Azure Container Apps Docs: Microsoft Learn
- OpenTelemetry Docs: Azure Monitor Integration
- Source Code: src/MDev.Dotnet.Azure.ContainerApps
⚙️ Operation
Installation
dotnet add package MDev.Dotnet.Azure.ContainerApps
OpenTelemetry Setup
using MDev.Dotnet.AspNetCore.OpenTelemetry.Apis.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register OpenTelemetry with custom meters
var customMeters = new List<string>
{
"MyApp.Orders",
"MyApp.Payments"
};
builder.RegisterOpenTelemetry(customMeters);
var app = builder.Build();
app.Run();
appsettings.json for OpenTelemetry
{
"OpenTelemetry": {
"ServiceType": "AppInsights",
"IgnoreErrorStatusCode": [404, 401]
}
}
For custom OTLP endpoints (e.g., Dynatrace):
{
"OpenTelemetry": {
"ServiceType": "Custom"
},
"OTEL_ENDPOINT": "https://your-otlp-endpoint.com",
"OTEL_ENDPOINT_AUTH": "Api-Token your-token",
"CONTAINER_APP_NAME": "myapp",
"CONTAINER_APP_REPLICA_NAME": "myapp-revision-1"
}
Implementing Async Operations with Dapr
Step 1: Create a Message Handler
using MDev.Dotnet.AspNetCore.AsyncOperations.Abstracts;
using MDev.Dotnet.AspNetCore.AsyncOperations.Messages;
public class OrderProcessingHandler : IAsyncOperationRequestMessageHandler
{
public string OperationType => "ProcessOrder";
public async Task<object> HandleAsync(
AsyncOperationRequestMessage message,
CancellationToken cancellationToken)
{
// Process your order
var orderId = message.Data["orderId"].ToString();
// Your business logic here
await ProcessOrderAsync(orderId);
return new { Success = true, OrderId = orderId };
}
}
Step 2: Register the Handler
builder.Services.AddScoped<IAsyncOperationRequestMessageHandler, OrderProcessingHandler>();
builder.Services.AddScoped<AsyncOperationRequestsService>();
Step 3: Create Your Dapr Controller
using MDev.Dotnet.AspNetCore.AsyncOperations.Controllers.v1;
using MDev.Dotnet.Dapr.Attributes;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/v1/dapr")]
public class MyDaprController : DaprHandlerController
{
public MyDaprController(AsyncOperationRequestsService service)
: base(service)
{
}
[HttpPost("orders")]
[RequireDaprApiToken]
public override Task<IActionResult> OperationRequestAsync(
[FromBody] AsyncOperationRequestMessage item,
CancellationToken cancellationToken)
{
return base.OperationRequestAsync(item, cancellationToken);
}
}
Accessing Container Apps Authentication
using MDev.Dotnet.Azure.ContainerApps.Authentication.Extensions;
public class MyController : ControllerBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
[HttpGet]
public IActionResult GetUserInfo()
{
var principal = _httpContextAccessor.GetMsClientPrincipal();
if (principal != null)
{
return Ok(new
{
UserId = principal.UserId,
UserName = principal.UserDetails,
Roles = principal.UserRoles
});
}
return Unauthorized();
}
}
MDev.Dotnet.Azure.CosmosDb
🎯 Highlight
Simplify Azure CosmosDb integration with Entity Framework Core. This package provides a one-line registration for CosmosDb contexts with managed identity support.
Key Features:
- ✅ Simple DbContext registration for CosmosDb
- ✅ Managed Identity (TokenCredential) support
- ✅ Configuration-based setup
- ✅ Scoped DbContext lifetime management
📚 Explain
This package simplifies the integration of Azure CosmosDb with Entity Framework Core by:
- DbContext Registration - Automatically configures EF Core with CosmosDb provider
- Credential Management - Uses Azure TokenCredential for secure authentication
- Configuration Binding - Reads CosmosDb settings from appsettings.json
Main Extension Method:
RegisterCosmosDb<T>()- Registers a DbContext with CosmosDb provider
🔗 Resources
- NuGet Package:
- CosmosDb Docs: Microsoft Learn
- EF Core CosmosDb: EF Core Documentation
- Source Code: src/MDev.Dotnet.Azure.CosmosDb
⚙️ Operation
Installation
dotnet add package MDev.Dotnet.Azure.CosmosDb
dotnet add package Azure.Identity
Define Your DbContext
using Microsoft.EntityFrameworkCore;
public class MyAppDbContext : DbContext
{
public MyAppDbContext(DbContextOptions<MyAppDbContext> options)
: base(options)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.ToContainer("Products")
.HasPartitionKey(p => p.Category);
modelBuilder.Entity<Order>()
.ToContainer("Orders")
.HasPartitionKey(o => o.CustomerId);
}
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
public class Order
{
public string Id { get; set; }
public string CustomerId { get; set; }
public List<string> ProductIds { get; set; }
public decimal Total { get; set; }
}
Register CosmosDb in Program.cs
using Azure.Identity;
using MDev.Dotnet.Azure.CosmosDb.Startup;
var builder = WebApplication.CreateBuilder(args);
// Use DefaultAzureCredential for managed identity
var credential = new DefaultAzureCredential();
// Or use specific credential type
// var credential = new ManagedIdentityCredential();
// var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
builder.RegisterCosmosDb<MyAppDbContext>(credential);
var app = builder.Build();
app.Run();
appsettings.json Configuration
{
"CosmosDb": {
"Endpoint": "https://your-account.documents.azure.com:443/",
"DatabaseName": "MyAppDatabase"
}
}
Using the DbContext
public class ProductService
{
private readonly MyAppDbContext _dbContext;
public ProductService(MyAppDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<Product> GetProductAsync(string id, string category)
{
return await _dbContext.Products
.WithPartitionKey(category)
.FirstOrDefaultAsync(p => p.Id == id);
}
public async Task CreateProductAsync(Product product)
{
_dbContext.Products.Add(product);
await _dbContext.SaveChangesAsync();
}
public async Task<List<Product>> GetProductsByCategoryAsync(string category)
{
return await _dbContext.Products
.WithPartitionKey(category)
.ToListAsync();
}
}
EnsureCreated (Development Only)
// In Program.cs for development environments
using (var scope = app.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<MyAppDbContext>();
await dbContext.Database.EnsureCreatedAsync();
}
MDev.Dotnet.Azure.StorageAccount
🎯 Highlight
Streamline Azure Storage operations with ready-to-use helpers for blob storage and queue management. Includes SAS token generation, blob operations, and queue client management.
Key Features:
- ✅ Blob upload/download with metadata support
- ✅ SAS token generation for secure blob access
- ✅ Container management (create, delete, list)
- ✅ Multiple queue client support with key-based registration
- ✅ Managed Identity (TokenCredential) support
- ✅ Base64 encoding support for queue messages
📚 Explain
This package provides two main helpers for Azure Storage operations:
PersistentService - Comprehensive blob storage operations
- Upload/download blobs
- Generate SAS URIs for secure access
- Container management
- Blob copying and deletion
- Metadata support
QueuesService - Queue client management
- Multiple queue support per application
- Key-based queue client registration
- Base64 message encoding option
Main Components:
RegisterAzureStorage()- Registers BlobServiceClient and QueueClientsPersistentService- Scoped service for blob operationsQueuesService- Keyed service for queue operations
🔗 Resources
- NuGet Package:
- Azure Storage Docs: Microsoft Learn
- Blob Storage: Blob Storage Documentation
- Queue Storage: Queue Storage Documentation
- Source Code: src/MDev.Dotnet.Azure.StorageAccount
⚙️ Operation
Installation
dotnet add package MDev.Dotnet.Azure.StorageAccount
dotnet add package Azure.Identity
Register Storage Account in Program.cs
using Azure.Identity;
using MDev.Dotnet.Azure.StorageAccount.Startup;
var builder = WebApplication.CreateBuilder(args);
// Use DefaultAzureCredential for managed identity
var credential = new DefaultAzureCredential();
builder.RegisterAzureStorage(credential);
var app = builder.Build();
app.Run();
appsettings.json Configuration
{
"StorageAccount": {
"BlobsEndpoint": "https://yourstorageaccount.blob.core.windows.net",
"QueuesEndpoint": "https://yourstorageaccount.queue.core.windows.net",
"QueueMessagesEncodeBase64": false,
"Queues": [
{
"Id": "orders",
"Queues": ["order-processing", "order-notifications"]
},
{
"Id": "reports",
"Queues": ["report-generation"]
}
]
}
}
Using PersistentService for Blob Operations
using MDev.Dotnet.Azure.StorageAccount.Helpers;
public class FileStorageService
{
private readonly PersistentService _persistentService;
private readonly ILogger<FileStorageService> _logger;
public FileStorageService(
PersistentService persistentService,
ILogger<FileStorageService> logger)
{
_persistentService = persistentService;
_logger = logger;
}
// Upload a file
public async Task<string> UploadFileAsync(
Stream fileStream,
string fileName,
string containerName = "documents")
{
var metadata = new Dictionary<string, string>
{
{ "UploadedBy", "user@example.com" },
{ "UploadDate", DateTime.UtcNow.ToString("O") }
};
await _persistentService.SaveOnBlobAsync(
containerName,
fileStream,
fileName,
metadata);
return await _persistentService.RetreiveBlobUriAsync(
containerName,
fileName);
}
// Download a file
public async Task<Stream> DownloadFileAsync(
string containerName,
string fileName)
{
return await _persistentService.DownloadBlobContentAsync(
containerName,
fileName);
}
// Generate secure access URL
public async Task<string> GetSecureUrlAsync(
string containerName,
string fileName)
{
return await _persistentService.RetreiveBlobUriAsync(
containerName,
fileName);
}
// Delete a file
public async Task DeleteFileAsync(
string containerName,
string fileName)
{
await _persistentService.DeleteBlobIfExistsAsync(
containerName,
fileName);
}
// List all files with prefix
public async Task<List<string>> ListFilesAsync(
string containerName,
string prefix)
{
return await _persistentService.RetreiveBlobsUriAsync(
containerName,
prefix);
}
// Copy a file
public async Task CopyFileAsync(
string sourceContainer,
string sourceFileName,
string destContainer,
string destFileName)
{
await _persistentService.CopyBlocFileAsync(
sourceContainer,
sourceFileName,
destContainer,
destFileName);
}
}
Using QueuesService for Queue Operations
using MDev.Dotnet.Azure.StorageAccount.Helpers;
public class OrderProcessingService
{
private readonly QueuesService _ordersQueue;
private readonly ILogger<OrderProcessingService> _logger;
// Inject using keyed service
public OrderProcessingService(
[FromKeyedServices("orders")] QueuesService ordersQueue,
ILogger<OrderProcessingService> logger)
{
_ordersQueue = ordersQueue;
_logger = logger;
}
public async Task QueueOrderAsync(string orderId)
{
var message = new OrderMessage
{
OrderId = orderId,
Timestamp = DateTime.UtcNow
};
var json = JsonSerializer.Serialize(message);
// Send to first queue in the "orders" group
await _ordersQueue.Clients[0].SendMessageAsync(json);
_logger.LogInformation("Order {OrderId} queued", orderId);
}
}
public class OrderMessage
{
public string OrderId { get; set; }
public DateTime Timestamp { get; set; }
}
Complete Example: File Upload API
[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
private readonly PersistentService _persistentService;
public FilesController(PersistentService persistentService)
{
_persistentService = persistentService;
}
[HttpPost("upload")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file uploaded");
using var stream = file.OpenReadStream();
var fileName = $"{Guid.NewGuid()}-{file.FileName}";
var metadata = new Dictionary<string, string>
{
{ "OriginalName", file.FileName },
{ "ContentType", file.ContentType },
{ "Size", file.Length.ToString() }
};
await _persistentService.SaveOnBlobAsync(
"uploads",
stream,
fileName,
metadata);
var url = await _persistentService.RetreiveBlobUriAsync(
"uploads",
fileName);
return Ok(new { Url = url, FileName = fileName });
}
[HttpGet("download/{fileName}")]
public async Task<IActionResult> DownloadFile(string fileName)
{
var stream = await _persistentService.DownloadBlobContentAsync(
"uploads",
fileName);
if (stream == Stream.Null)
return NotFound();
return File(stream, "application/octet-stream", fileName);
}
[HttpDelete("{fileName}")]
public async Task<IActionResult> DeleteFile(string fileName)
{
await _persistentService.DeleteBlobIfExistsAsync(
"uploads",
fileName);
return NoContent();
}
}
Additional Resources
- Wiki Documentation: Complete documentation on the Wiki
- Code Documentation: All public APIs include XML documentation comments
- Azure Documentation: Microsoft Learn
- Sample Projects: Check the source code for inline examples and patterns
Support / Contribute
If you have any question, problem or suggestion, create an issue or fork the project and create a Pull Request.
Build Status
License
This project is licensed under the terms specified in the LICENSE file.
Made with ❤️ for the .NET Community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 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. |
-
net10.0
- Asp.Versioning.Mvc (>= 8.1.0)
- Azure.Monitor.OpenTelemetry.AspNetCore (>= 1.4.0)
- Azure.Monitor.OpenTelemetry.Exporter (>= 1.5.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.14.0)
- OpenTelemetry.Extensions.Hosting (>= 1.14.0)
- ServiceCollectionHelpers.AssemblyFinder (>= 1.7.0)
-
net9.0
- Asp.Versioning.Mvc (>= 8.1.0)
- Azure.Monitor.OpenTelemetry.AspNetCore (>= 1.4.0)
- Azure.Monitor.OpenTelemetry.Exporter (>= 1.5.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.14.0)
- OpenTelemetry.Extensions.Hosting (>= 1.14.0)
- ServiceCollectionHelpers.AssemblyFinder (>= 1.7.0)
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.14.0 | 76 | 2/8/2026 |
| 1.13.0 | 416 | 12/10/2025 |
| 1.13.0-preview-080 | 424 | 12/10/2025 |
| 1.12.0 | 177 | 11/24/2025 |
| 1.12.0-preview-078 | 265 | 11/13/2025 |
| 1.11.0 | 1,612 | 8/3/2025 |
| 1.11.0-preview-076 | 149 | 7/29/2025 |
| 1.10.0 | 576 | 7/22/2025 |
| 1.10.0-preview-074 | 539 | 7/22/2025 |
| 1.10.0-preview-073 | 713 | 7/20/2025 |
| 1.10.0-preview-072 | 345 | 7/20/2025 |
| 1.10.0-preview-071 | 155 | 7/18/2025 |
| 1.10.0-preview-069 | 174 | 7/16/2025 |
| 1.9.0 | 181 | 7/15/2025 |
| 1.9.0-preview-067 | 184 | 7/13/2025 |
| 1.8.0 | 186 | 6/17/2025 |
| 1.8.0-preview-065 | 178 | 6/17/2025 |
| 1.8.0-preview-064 | 209 | 6/16/2025 |
| 1.8.0-preview-063 | 179 | 6/16/2025 |
| 1.8.0-preview-062 | 174 | 6/16/2025 |
| 1.7.0 | 967 | 4/23/2025 |
| 1.7.0-preview-060 | 339 | 4/23/2025 |
| 1.7.0-preview-059 | 203 | 4/23/2025 |
| 1.6.0 | 222 | 4/21/2025 |
| 1.6.0-preview-057 | 199 | 4/21/2025 |
| 1.5.0 | 217 | 4/21/2025 |
| 1.5.0-preview-054 | 192 | 4/21/2025 |
| 1.5.0-preview-053 | 212 | 4/20/2025 |
| 1.4.0 | 739 | 4/2/2025 |
| 1.4.0-preview-051 | 189 | 4/2/2025 |
| 1.4.0-preview-050 | 196 | 4/2/2025 |
| 1.3.0 | 202 | 4/1/2025 |
| 1.3.0-preview-048 | 130 | 3/29/2025 |
| 1.2.0 | 506 | 3/24/2025 |
| 1.2.0-preview-046 | 692 | 2/26/2025 |
| 1.1.0 | 342 | 2/19/2025 |
| 1.1.0-preview-044 | 137 | 2/19/2025 |
| 1.1.0-preview-043 | 212 | 2/19/2025 |
| 1.1.0-preview-042 | 146 | 2/19/2025 |
| 1.1.0-preview-041 | 145 | 2/13/2025 |
| 1.1.0-preview-040 | 188 | 1/18/2025 |
| 1.1.0-preview-037 | 512 | 1/12/2025 |
| 1.1.0-preview-036 | 271 | 12/5/2024 |
| 1.0.0 | 781 | 11/17/2024 |
| 1.0.0-preview-024 | 128 | 11/17/2024 |
| 1.0.0-preview-023 | 291 | 11/14/2024 |
| 1.0.0-preview-022 | 116 | 11/7/2024 |
| 1.0.0-preview-020 | 84 | 11/7/2024 |
| 1.0.0-preview-019 | 389 | 10/21/2024 |
| 1.0.0-preview-017 | 92 | 10/19/2024 |
| 1.0.0-preview-016 | 137 | 10/19/2024 |
| 1.0.0-preview-015 | 175 | 10/18/2024 |
| 1.0.0-preview-013 | 586 | 8/19/2024 |
| 1.0.0-preview-012 | 299 | 8/18/2024 |
| 1.0.0-preview-011 | 274 | 7/23/2024 |
| 1.0.0-preview-010 | 130 | 7/23/2024 |
| 1.0.0-preview-009 | 156 | 7/18/2024 |
| 1.0.0-preview-008 | 129 | 7/18/2024 |
| 1.0.0-preview-007 | 129 | 7/18/2024 |
| 1.0.0-preview-006 | 133 | 7/17/2024 |
| 1.0.0-preview-005 | 144 | 7/17/2024 |
| 1.0.0-preview-004 | 129 | 7/16/2024 |
| 1.0.0-preview-003 | 116 | 7/16/2024 |
| 1.0.0-preview-002 | 133 | 7/16/2024 |