O24Platform 2.5.2
dotnet add package O24Platform --version 2.5.2
NuGet\Install-Package O24Platform -Version 2.5.2
<PackageReference Include="O24Platform" Version="2.5.2" />
<PackageVersion Include="O24Platform" Version="2.5.2" />
<PackageReference Include="O24Platform" />
paket add O24Platform --version 2.5.2
#r "nuget: O24Platform, 2.5.2"
#:package O24Platform@2.5.2
#addin nuget:?package=O24Platform&version=2.5.2
#tool nuget:?package=O24Platform&version=2.5.2
O24Platform
Nền tảng thư viện dùng chung cho các dự án O24 — hỗ trợ Open API, workflow, queue (RabbitMQ), migration đa database, logging và tích hợp microservice.
Cài đặt
dotnet add package O24Platform
Cấu hình nhanh
Thêm section O24OpenAPIConfiguration vào App_Data/appsettings.json (hoặc secret store tương ứng):
"O24OpenAPIConfiguration": {
"YourServiceID": "MS1",
"IsMicroservice": true,
"ConnectToWFO": true,
"WFOGrpcURL": "https://wfo.example.com",
"YourGrpcURL": "https://your-service.example.com"
}
IsMicroservice = false: tắt queue, RabbitMQ event bus consumer và đăng ký WFO — phù hợp service standalone/API thuần.DataWarehouseEntities: Danh sách tên các entity cần đồng bộ sang Data Warehouse (DWH) theo cơ chế Transactional Outbox. Ví dụ:["UserAccount", "Order", "Transaction"].
Release Notes
2.5.0 — 2026-09-06
Data Warehouse Synchronization Foundation (Transactional Outbox Pattern)
- Kiến trúc đồng bộ Transactional Outbox:
- Bổ sung
TableSyncEvent, entityOutboxMessage,OutboxMessageBuildervà cấu hìnhDataWarehouseEntities(HashSet) trongO24OpenAPIConfiguration. - Tự động ghi OutboxMessage trong cùng Database Transaction với entity nghiệp vụ cho cả thao tác đơn lẻ và hàng loạt (
InsertAsync,Update,Delete,BulkInsert,BulkDelete,InsertWithoutAuditAsync). Đảm bảo tính toàn vẹn ACID, không bao giờ sinh event ma khi transaction rollback.
- Bổ sung
- Khóa hàng đa tiến trình tự nhiên (Multi-Instance Concurrency Protection):
OutboxPublisherJobhỗ trợ scale nhiều replica/pod chạy song song mà không tranh chấp hay trùng lặp tin nhắn, không phụ thuộc Redis lock.- Sử dụng khóa hàng bản địa của RDBMS:
WITH (ROWLOCK, UPDLOCK, READPAST)(SQL Server) vàFOR UPDATE SKIP LOCKED(PostgreSQL, MySQL 8.0+, Oracle). - Tích hợp cơ chế tự phục hồi Lease Timeout (5 phút) và tự động dọn dẹp log outbox đã gửi thành công sau 7 ngày (1 lần/ngày).
- Điều hướng sự kiện riêng biệt (Selective Service Routing):
- Bổ sung attribute
[ServiceRouted]và interfaceITargetServiceRoutedđể RabbitMQ định tuyến routing key{ServiceId}.{EventName}chính xác đến từng microservice mục tiêu, loại bỏ hoàn toàn broadcast thừa thãi.
- Bổ sung attribute
- Tự chữa lành & Đối soát dữ liệu (Event-Driven Reconciliation & Self-Healing):
- Tích hợp sẵn
DwhTableAuditRequestHandlerđể phục vụ job đối soát ban đêm từ DWH. - Tích hợp sẵn
DwhDataBackfillRequestHandlersử dụng kỹ thuật Keyset Pagination (WHERE [Id] > @lastId ORDER BY [Id] LIMIT {batchSize}) để stream dữ liệu bù đắp hoặc khởi tạo bảng lịch sử lần đầu mà không làm khóa bảng hay tràn bộ nhớ RAM.
- Tích hợp sẵn
2.4.0 — 2026-09-04
gRPC Communication Foundation
- Tích hợp và chuẩn hoá toàn bộ hạ tầng gRPC dùng chung vào platform:
- Protobuf Envelope (
common.proto):GrpcRequest,GrpcResponse,GrpcResponseCode(SUCCESS=0,FAIL=-1) chuẩn hoá payload envelope trong namespaceO24OpenAPI.Grpc.Common. - Interceptors chuẩn hoá:
GrpcClientOutboundInterceptor: Tự động đính kèmwork_contextmetadata, đo latency, Serilog structured logging (LogType.Grpc,Direction: Out), phòng vệ null unary response.GrpcServerInboundInterceptor: Tự động bóc táchwork_contextnạp vàoWorkContext/EngineContext, mởAsyncServiceScope, chuẩn hoá exception thànhGrpcResponsefail envelope, ghi log Inbound.- Hỗ trợ đầy đủ Unary và ServerStreaming calls.
- Client Factory & Channel Pooling:
IGrpcClientFactory&GrpcClientFactory: PoolingGrpcChannel, auto-reconnect khi transient failure, sinh client động qua Expression Tree CallInvoker, tích hợp service discovery độc lập quaIWFOGrpcClientBaseService.IGrpcClient<T>&ClientGrpc<T>generic wrapper cho DI container.
- Base Client & Server Executor:
BaseGrpcClientService: Template methodInvokeAsync<TResult>bọc header, parse JSON sang strongly-typed model và log lỗi Serilog.GrpcExecutor: HelperExecuteAsynccho gRPC server methods.
- Extensions, Logging & Lifecycle:
GrpcExtensions:CallAsync<TResult>,GetGrpcResponseAsync,ToFailResponse,NullResponseFailure.GrpcCallLogger: Ghi log có cấu trúc Serilog cho gRPC.WfoServiceRegistryLifetimeService: Tự động unregister service endpoint khi host shutdown.AddO24GrpcPlatform: Extension đăng ký toàn bộ DI hạ tầng gRPC cho ASP.NET Core service.
- Protobuf Envelope (
2.3.0 — 2026-08-17
Log Download API & Service
- Thêm các endpoint quản lý và tải file log:
GET /api/logs/list,GET /api/logs/files,GET /api/logs/download,GET /api/logs/download-zip. - Hỗ trợ quét tìm kiếm file log theo khoảng thời gian/LogType/SearchPattern, đọc non-blocking (
FileShare.ReadWrite), và nén ZIP trực tiếp stream không tạo file tạm trên đĩa.
Swagger Session Validation Middleware
- Bổ sung
SwaggerWorkContextMiddlewaretự động bắt request gọi từ Swagger UI (X-From-Swaggerheader hoặcRefererURL), xác thực Session Token qua gRPCISessionValidationService(CTH) và nạpWorkContext. - Trả về JSON
401 Unauthorizedchứaexecution_idchuẩn hoá nếu token thiếu hoặc hết hạn. - Phân lập hoàn toàn, không can thiệp hay ảnh hưởng tới luồng gọi inter-service giữa các microservices.
Serilog Diagnostics & Swagger UI
- Bật
Serilog.Debugging.SelfLog.Enableghi lỗi ra Console nếu xảy ra sự cố tạo/ghi file log. - Tự động trích xuất Token trên Swagger UI bằng JavaScript Request Interceptor để đính kèm
Authorization: Bearer <token>vào mọi HTTP request từ Swagger UI.
2.2.20 — 2026-08-06
Entity builders & schema
- Bổ sung
EntityFieldBuilder,TransactionDetailsBuilder;O24OpenAPIServiceBuilderthêmMediatorKey. - Gom builder theo entity/file:
Language,Log,Setting,StoredCommand(class theo provider: SqlServer/MySQL/PostgreSQL vs Oracle qua[DatabaseType]). EntityBuilderStringColumnCatalog+EntityBuilderSchemaAligner: trên DB đã có, probe length + nullability; chỉAlterColumnkhi lệch builder (SqlServer, PostgreSQL, MySQL, Oracle).- Migrations Update:
EntityBuilderSchemaAlignmentMigration,EntityBuilderSchemaNullableAlignmentMigration(và aligner idempotent cho migration length cũ).
Index
PlatformEntityIndexesMigration: tạo index không unique cho bảng platform; lỗi từng index → log (BusinessLogHelper) và bỏ qua, không throw fail cả migration.
O24OpenAPIService (CQRS fw)
POST api/o24openapi-services/advance-search— lọc theo field builder.POST api/o24openapi-services/export-json— export JSON migration theo cùng điều kiện advance search.POST api/o24openapi-services/import-json— import JSON (upsert theoStepCode).- Seed step WFO:
DataO24OpenAPIServiceSearchExportMigration.
2.2.19 — 2026-08-06
CodeList filter theo CodeId
Bổ sung field CodeId vào GetCodeListByGroupAndNameQuery và CodeListGroupAndNameRequestModel.
GET_CODE_LIST_BY_GROUP_AND_NAME hỗ trợ lọc danh sách theo tiền tố CodeId.
CodeListService.GetByGroupAndName hỗ trợ cùng cơ chế lọc theo CodeId.
Việc lọc không phân biệt chữ hoa/chữ thường.
CodeId là tham số tùy chọn:
Không truyền, truyền null, chuỗi rỗng hoặc khoảng trắng → bỏ qua điều kiện lọc.
Truyền giá trị, ví dụ HPH → trả về các mã bắt đầu bằng HPH, như HPH07059, HPH07062, HPH07068, HPH08003.
Bổ sung kiểm tra CodeId khác null trước khi thực hiện StartsWith, tránh lỗi với dữ liệu không có mã.
Ví dụ request:
{
"code_id": "HPH",
"page_index": 0,
"page_size": 20
}
2.2.18 — 2026-08-05
DI, EngineContext và AsyncScope
IEngine.CreateScope(WorkContextTemplate?)vàCaptureWorkContextSnapshot()— snapshot WorkContext từAsyncScope→ HTTP → ambient scope (xử lý scope đã dispose).AsyncScope:TryGetServiceProvider(),Reset()(chỉ xóa pointer) vsClear()(dispose + reset); bỏ propertyServiceProviderdễ NRE.TaskUtils/TransactionDispatcher: capture snapshot trên thread gọi,CreateScope, restore ambient trongfinally.QueueClient(command/event):CreateScope(template); dispose scope message + restore/Resetambient (khôngClear()kèmusing).StartEngine: khôi phụcAsyncScopesau migration/queue init (tránh trỏ scope đã dispose).- Ghi chú trên
EngineContext.Current: ưu tiên constructor DI; locator chỉ khi bắt buộc.
Health & runtime
MapO24HealthEndpoints:GET /api/health/ping,GET /api/health/info(version, uptime, … quaIAppRuntimeInfoProvider).- Startup banner dùng runtime info khi có.
Logging HTTP
RestApiLoggingMiddleware: giới hạn kích thước body log, redact header,LogSanitizer; injectWorkContext.CorrelationIdMiddleware: tôn trọng headerX-Correlation-ID.- Cấu hình qua section
Logging(LoggingConfig).
Event bus & queue
IEventBus.PublishAsync(eventName, payload)— publish theo tên + object, không bắt buộc deserializeIntegrationEvent.RabbitMQEventBus/NoOpEventBuscập nhật tương ứng.
Data & cache
- Migration
PlatformEntityIndexesMigration: index hiệu năng (không unique) cho entity platform (ví dụLocaleStringResource, audit, CDC config, …). DistributedCacheManager.ClearAll(): xóa theo key đã track, không dùng RedisKEYS *.
Startup
CreateDatabaseAsync()gọi trongStartEngine(async), bỏ.Wait()trên request pipeline.
Gợi ý dùng EngineContext (khi không inject được DI)
- Request API:
EngineContext.Current.Resolve<T>()thường ổn (ưu tiênHttpContext.RequestServices). - Background:
CaptureWorkContextSnapshot()trên caller →using var scope = EngineContext.Current.CreateScope(snapshot)→ restore ambient; hoặcTaskUtils.RunAsync/RunInNewScope. - Không gọi
AsyncScope.Clear()trongfinallynếu scope đãDispose()bằngusing/biến local.
2.2.17 — 2026-07-31
JSON static files (sandbox theo thư mục cấu hình)
IJsonStaticFileService: search / get / update file.jsontrongRootPath; chặn path traversal và path ngoài root.- Extension DI:
AddJsonStaticFileService— root từO24OpenAPIConfiguration.JsonStaticFileRootPath(mặc định./StaticConfig). - CQRS (
MediatorKey = "fw"):POST api/json-static-files/searchPOST api/json-static-files/getPOST api/json-static-files/update
O24Resource / localization
- Bổ sung mã lỗi dùng chung (vi/en):
NotFound,NotExists,InvalidInput, path/file/JSON validation, unique/conflict, … — cùng format class phẳng như các hằng validation hiện có. - Migration
O24ResourceMigrationseed resource mới quaBaseResourceMigration.
Ví dụ đăng ký host (RootPath lấy từ O24OpenAPIConfiguration.JsonStaticFileRootPath):
"O24OpenAPIConfiguration": {
"JsonStaticFileRootPath": "./StaticConfig"
}
builder.AddJsonStaticFileService();
2.2.16 — 2026-07-24
Connection string password decrypt / escape theo DataProvider
DataConfig.DecryptConnectionStringescape password theo từngDataProvider(Oracle / SqlServer / MySql / PostgreSQL).- Oracle: không bọc single-quote (tránh
ORA-01017vớiOracle.ManagedDataAccess.Core23.x); chỉ double-quote khi password có delimiter. - SqlServer: single-quote khi cần; MySQL / PostgreSQL: double-quote khi cần.
- Đổi
DataProvidersẽ invalidate cache decrypted connection string.
2.2.15 — 2026-07-23
Stored procedure workflow V2
- Thêm
ProcessNumber.StoredProcedureV2(6). O24OpenAPIServiceManagerhỗ trợ luồngHandleStoredProcedureWorkflowV2khiprocessing_version=StoredProcedureV2.BaseQueuebổ sungCallStoredProcedureV2và chuẩn hóa response data (snake_case) cho stored procedure V2.
2.2.14 — 2026-07-22
WorkContext scope
- Thêm
WorkContext.Scope/WorkContextTemplate.ScopevàSetScope. - Thêm abstraction
IScopeHandlerđể service tự implement xử lý scope. O24OpenAPIServiceManagergọiIScopeHandler.HandleScope()trước khi execute workflow khiScopecó giá trị.
2.2.13 — 2026-07-22
CodeList CQRS / WorkflowStep
- Thêm feature cho domain
C_CODELIST(LinKit CQRS +[WorkflowStep]):GET_CODE_LIST_BY_GROUP_AND_NAMEGET_CODE_LIST_BY_IDCREATE_CODE_LISTUPDATE_CODE_LISTDELETE_CODE_LIST
- Response dùng
CodeListResponseModel; caption resolve theoLanguagequaCodeListUtils.
Platform WorkflowStepInvoker
- Thêm
O24Analyzerđể genWorkflowStepInvokertrong assemblyO24Platform. - Đăng ký
IWorkflowStepInvokerkeyed"fw"cùngAddLinKitCqrs("fw")— service dùng platform có thể invoke step CodeList qua mediator keyfw.
2.2.12 — 2026-07-21
Read/write database split (read replica)
- Thêm cấu hình opt-in trên
ConnectionStrings(DataConfig):UseReadReplica: bật dùng read replica.ReadConnectionString: connection string replica (decrypt giốngConnectionString).- Khi tắt hoặc thiếu read string → toàn bộ traffic vẫn đi primary (backward compatible).
IDataConnectionFactoryhỗ trợDbAccessMode(Write|Read):- Query dùng read khi replica được bật.
- Trong transaction (command /
TransactionBehavior) luôn force Write để đảm bảo read-your-writes.
BaseRepositorytách connection theo thao tác:- Đọc (
Table,Get*,Count,Search*) → Read. - Ghi (
Insert/Update/Delete/ bulk / audit) và mutate-by-query (WriteTable,WriteTableFilter) → Write.
- Đọc (
Ví dụ cấu hình:
"ConnectionStrings": {
"ConnectionString": "...",
"ReadConnectionString": "...",
"UseReadReplica": true
}
2.2.11 — 2026-07-20
Event Dispatching
- Hỗ trợ tham số
mediatorKeytrongIEventDispatcher.DispatchAsyncvàLinKitEventDispatcherđể resolveIMediatorinstance theo tên (hỗ trợ sử dụng multi-mediator).
2.2.10 — 2026-07-19
Multi-database execution trên ServiceDBContext
- Bật đầy đủ EF Core provider cho SQL Server, PostgreSQL, MySQL/MariaDB và Oracle trong
OnConfiguring(theoDataConfig.DataProvider/RDBMSType). - Thống nhất execute SQL, query, DML, paged query và stored procedure qua dialect helpers (
SqlServer|PostgreSQL|MySql|Oracle):- Parameter prefix (
@/:), identifier quoting ([]/""/`), LIKE concat. - Schema switch:
USE/SET search_path/ALTER SESSION SET CURRENT_SCHEMA. - Workflow SP:
EXEC/CALL/BEGIN … ENDvới output parameter chung.
- Parameter prefix (
- Thêm package
Npgsql.EntityFrameworkCore.PostgreSQL,Pomelo.EntityFrameworkCore.MySql; cập nhật EF Core9.0.1,MySqlConnector2.4.0.
2.2.9 — 2026-07-19
Microservice opt-out
- Thêm
O24OpenAPIConfiguration.IsMicroservice(mặc địnhtrue) để xác định service có tham gia hệ thống microservice hay không. - Khi
IsMicroservice = false:- Không khởi tạo
QueueClient, không gọi WFOQueryServiceInfo, không chạy reconnect scheduler. - Không đăng ký
RabbitMQEventBusconsumer; dùngNoOpEventBuschoIEventBus. - Bỏ qua
SyncProjectCodeAsyncvàInitializeMessageQueue. - Startup banner hiển thị
Queue Status: DISABLED.
- Không khởi tạo
Bug fix
CodeListService.GetByGroupAndName: trả về thêm fieldMCaptiontrong kết quả phân trang.
2.2.8 — 2026-07-17
- Bổ sung interface và implementation xử lý event.
- Refactor quản lý domain events.
2.2.6 — 2026-07-16
- Thêm
ProjectCodevàoO24OpenAPIConfiguration. - Đồng bộ project code từ WFO qua
SyncProjectCodeAsync.
2.2.x (trước 2.2.6)
- Chuẩn hóa pagination (
PageIndex, offset) trênPagedListvàServiceDBContext. - RabbitMQ event bus với partition-based dispatch.
- Data provider abstraction (SQL Server, Oracle, MySQL, PostgreSQL) và migration infrastructure.
- Workflow step source generator,
O24OpenAPIServiceManager, logging Serilog, schedule tasks.
| Product | Versions 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. |
-
net10.0
- AutoMapper (>= 13.0.1)
- BouncyCastle.Cryptography (>= 2.6.2)
- CsvHelper (>= 33.0.1)
- Dapper (>= 2.1.72)
- FluentMigrator.Runner (>= 5.2.0)
- FluentValidation (>= 11.9.2)
- FluentValidation.AspNetCore (>= 11.3.0)
- Google.Protobuf (>= 3.33.5)
- Grpc.AspNetCore.Server (>= 2.76.0)
- Grpc.Core.Api (>= 2.76.0)
- Grpc.Net.Client (>= 2.76.0)
- Humanizer.Core (>= 2.14.1)
- Linh.CodeEngine (>= 1.0.3)
- LinKit.Json.Runtime (>= 1.2.0)
- linq2db (>= 6.1.0)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.9)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 10.0.2)
- Microsoft.AspNetCore.OpenApi (>= 10.0.0)
- Microsoft.ClearScript (>= 7.4.5)
- Microsoft.EntityFrameworkCore (>= 9.0.1)
- Microsoft.EntityFrameworkCore.SqlServer (>= 9.0.1)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Caching.SqlServer (>= 9.0.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- MySqlConnector (>= 2.4.0)
- Newtonsoft.Json (>= 13.0.4)
- Npgsql (>= 10.0.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 9.0.4)
- O24OpenAPI.KeyVault (>= 1.3.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.15.0)
- OpenTelemetry.Extensions.Hosting (>= 1.15.0)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.15.0)
- OpenTelemetry.Instrumentation.GrpcNetClient (>= 1.12.0-beta.1)
- OpenTelemetry.Instrumentation.Http (>= 1.15.0)
- OpenTelemetry.Instrumentation.Runtime (>= 1.15.0)
- Oracle.EntityFrameworkCore (>= 9.23.26000)
- Oracle.ManagedDataAccess.Core (>= 23.26.0)
- Polly.Core (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 9.0.0)
- RabbitMQ.Client (>= 7.0.0)
- Serilog.AspNetCore (>= 8.0.1)
- Serilog.Sinks.Async (>= 1.5.0)
- Serilog.Sinks.File (>= 5.0.0)
- Serilog.Sinks.Map (>= 2.0.0)
- Serilog.Sinks.PeriodicBatching (>= 5.0.0)
- StackExchange.Redis (>= 2.8.31)
- Swashbuckle.AspNetCore.ReDoc (>= 10.0.1)
- Swashbuckle.AspNetCore.SwaggerGen (>= 10.0.1)
- Swashbuckle.AspNetCore.SwaggerUI (>= 10.0.1)
- System.Linq.Dynamic.Core (>= 1.6.0.1)
- Z.Expressions.Eval (>= 6.2.4)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on O24Platform:
| Package | Downloads |
|---|---|
|
O24Kit
Bộ Kit cho O24OpenAPI (Keyvault, Signature, Models...) |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.5.2 | 0 | 9/6/2026 |
| 2.4.0 | 45 | 9/4/2026 |
| 2.3.0 | 179 | 8/17/2026 |
| 2.2.20.15 | 66 | 8/17/2026 |
| 2.2.20.14 | 70 | 8/17/2026 |
| 2.2.20.13 | 56 | 8/17/2026 |
| 2.2.20.12 | 68 | 8/17/2026 |
| 2.2.20.11 | 69 | 8/17/2026 |
| 2.2.20.10 | 82 | 8/14/2026 |
| 2.2.20.9 | 69 | 8/14/2026 |
| 2.2.20.8 | 70 | 8/14/2026 |
| 2.2.20.7 | 86 | 8/12/2026 |
| 2.2.20.6 | 99 | 8/8/2026 |
| 2.2.20.2 | 80 | 8/6/2026 |
2.5.1: Sửa namespace O24OpenAPI.Contracts.Events tránh xung đột tên type Contract trong các microservices và tối ưu transactional outbox.