F88.Camunda.Orchestrator.Library
3.0.0
dotnet add package F88.Camunda.Orchestrator.Library --version 3.0.0
NuGet\Install-Package F88.Camunda.Orchestrator.Library -Version 3.0.0
<PackageReference Include="F88.Camunda.Orchestrator.Library" Version="3.0.0" />
<PackageVersion Include="F88.Camunda.Orchestrator.Library" Version="3.0.0" />
<PackageReference Include="F88.Camunda.Orchestrator.Library" />
paket add F88.Camunda.Orchestrator.Library --version 3.0.0
#r "nuget: F88.Camunda.Orchestrator.Library, 3.0.0"
#:package F88.Camunda.Orchestrator.Library@3.0.0
#addin nuget:?package=F88.Camunda.Orchestrator.Library&version=3.0.0
#tool nuget:?package=F88.Camunda.Orchestrator.Library&version=3.0.0
Hướng dẫn sử dụng Orchestrator.Library DLL
📦 Các cách import DLL vào project khác
1. Sử dụng trực tiếp file DLL
Bước 1: Copy DLL files
Copy các file sau từ bin/Release/net8.0/
vào project đích:
Orchestrator.Library.dll
Orchestrator.Library.deps.json
(nếu cần)
Bước 2: Thêm reference trong project file (.csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="Orchestrator.Library">
<HintPath>lib\Orchestrator.Library.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Orchestrator.Library\Orchestrator.Library.csproj" />
</ItemGroup>
</Project>
Bước 3: Thêm using statements
using Orchestrator.Library.Services;
using Orchestrator.Library.Workers;
using Orchestrator.Library.Models;
using Orchestrator.Library.Exceptions;
2. Sử dụng NuGet Package (Khuyến nghị)
Bước 1: Tạo NuGet Package
dotnet pack --configuration Release
Bước 2: Thêm NuGet Package
dotnet add package Orchestrator.Library --version 1.0.0
Hoặc thêm vào .csproj
:
<ItemGroup>
<PackageReference Include="Orchestrator.Library" Version="1.0.0" />
</ItemGroup>
3. Sử dụng ProjectReference (Trong cùng solution)
<ItemGroup>
<ProjectReference Include="..\Orchestrator.Library\Orchestrator.Library.csproj" />
</ItemGroup>
🔧 Setup trong Project đích
1. Web Application (.NET 6+)
// Program.cs
using Orchestrator.Library.Services;
using Orchestrator.Library.Models;
var builder = WebApplication.CreateBuilder();
// Đăng ký ZeebeService
builder.Services.AddZeebeService(provider =>
{
var configuration = provider.GetRequiredService<IConfiguration>();
var zeebeUrl = configuration["Zeebe:GatewayAddress"] ?? "localhost:26500";
return ZeebeClient.Builder()
.UseGatewayAddress(zeebeUrl)
.UsePlainText()
.Build();
});
// Đăng ký Kafka configuration
builder.Services.Configure<BaseConfigKafka>(builder.Configuration.GetSection("Kafka"));
// Đăng ký KafkaMessageService
builder.Services.AddSingleton<IKafkaMessageService, KafkaMessageService>();
// Đăng ký workers
builder.Services.AddWorker<MyWorker, MyJobProcessor, MyJobData>();
var app = builder.Build();
app.Run();
2. Console Application
// Program.cs
using Orchestrator.Library.Services;
using Microsoft.Extensions.Hosting;
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Đăng ký ZeebeService
services.AddZeebeService(provider =>
{
var configuration = provider.GetRequiredService<IConfiguration>();
var zeebeUrl = configuration["Zeebe:GatewayAddress"] ?? "localhost:26500";
return ZeebeClient.Builder()
.UseGatewayAddress(zeebeUrl)
.UsePlainText()
.Build();
});
// Đăng ký Kafka configuration
services.Configure<BaseConfigKafka>(context.Configuration.GetSection("Kafka"));
// Đăng ký KafkaMessageService
services.AddSingleton<IKafkaMessageService, KafkaMessageService>();
// Đăng ký workers
services.AddWorker<MyWorker, MyJobProcessor, MyJobData>();
// Đăng ký hosted services
services.AddHostedService<MyWorkerHostedService>();
})
.Build();
host.Run();
📋 Dependencies cần thiết
NuGet Packages cần thêm vào project đích:
<ItemGroup>
<PackageReference Include="Zeebe.Client" Version="8.3.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Confluent.Kafka" Version="2.3.0" />
</ItemGroup>
🏭 Tạo Worker và Processor
1. Tạo Job Data Model
// MyJobData.cs
namespace MyProject.Models;
public class MyJobData
{
public string Message { get; set; } = string.Empty;
public int Priority { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
2. Tạo Job Processor
// MyJobProcessor.cs
using Orchestrator.Library.Services;
using Orchestrator.Library.Workers;
using Orchestrator.Library.Exceptions;
using MyProject.Models;
namespace MyProject.Workers;
public class MyJobProcessor : IJobProcessor<MyJobData>
{
private readonly IZeebeService _zeebeService;
private readonly ILogger<MyJobProcessor> _logger;
public MyJobProcessor(IZeebeService zeebeService, ILogger<MyJobProcessor> logger)
{
_zeebeService = zeebeService;
_logger = logger;
}
public async Task ProcessJobAsync(IJobClient jobClient, IJob job, MyJobData data, CancellationToken stoppingToken)
{
try
{
_logger.LogInformation("Processing job. JobKey: {JobKey}, Message: {Message}",
job.Key, data.Message);
// Xử lý business logic
var result = await ProcessBusinessLogic(data);
// Complete job
await _zeebeService.CompleteJobAsync(jobClient, job.Key, result);
// Publish message
await _zeebeService.PublishMessageAsync(
"job-completed",
$"job-{job.Key}",
new { JobKey = job.Key, Result = result }
);
_logger.LogInformation("Job completed successfully. JobKey: {JobKey}", job.Key);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing job. JobKey: {JobKey}", job.Key);
await _zeebeService.ThrowErrorAsync(jobClient, job.Key, "PROCESSING_ERROR", ex.Message);
}
}
private async Task<object> ProcessBusinessLogic(MyJobData data)
{
// Implement your business logic here
await Task.Delay(1000); // Simulate processing
return new {
Success = true,
ProcessedMessage = data.Message.ToUpper(),
ProcessedAt = DateTime.UtcNow
};
}
}
3. Tạo Worker
// MyWorker.cs
using Orchestrator.Library.Workers;
using Orchestrator.Library.Services;
using MyProject.Models;
namespace MyProject.Workers;
public class MyWorker : EnhancedGenericWorker<MyJobData>
{
public MyWorker(
IZeebeClient zeebeClient,
ILogger<MyWorker> logger,
IOptions<BaseConfigKafka> configKafka,
IJobProcessor<MyJobData> jobProcessor,
IZeebeService zeebeService,
IKafkaMessageService? kafkaMessageService = null)
: base(zeebeClient, logger, "my-job-type", configKafka, jobProcessor, kafkaMessageService, zeebeService)
{
}
}
4. Tạo Hosted Service
// MyWorkerHostedService.cs
using Microsoft.Extensions.Hosting;
using MyProject.Workers;
namespace MyProject.Services;
public class MyWorkerHostedService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<MyWorkerHostedService> _logger;
public MyWorkerHostedService(IServiceProvider serviceProvider, ILogger<MyWorkerHostedService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Starting My Worker Hosted Service");
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = _serviceProvider.CreateScope();
var worker = scope.ServiceProvider.GetRequiredService<MyWorker>();
// Worker sẽ tự động xử lý jobs
await Task.Delay(1000, stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in worker hosted service");
await Task.Delay(5000, stoppingToken); // Wait before retry
}
}
}
}
⚙️ Configuration
appsettings.json
{
"Zeebe": {
"GatewayAddress": "localhost:26500"
},
"Kafka": {
"BootstrapServers": "localhost:9092",
"GroupId": "my-worker-group"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Orchestrator.Library": "Debug",
"MyProject": "Debug"
}
}
}
🧪 Testing
Unit Test Example
// MyJobProcessorTests.cs
using Moq;
using Orchestrator.Library.Services;
using MyProject.Workers;
using MyProject.Models;
namespace MyProject.Tests;
[TestClass]
public class MyJobProcessorTests
{
[TestMethod]
public async Task ProcessJobAsync_ShouldCompleteJobSuccessfully()
{
// Arrange
var mockZeebeService = new Mock<IZeebeService>();
var mockLogger = new Mock<ILogger<MyJobProcessor>>();
var processor = new MyJobProcessor(mockZeebeService.Object, mockLogger.Object);
var jobClient = new Mock<IJobClient>();
var job = new Mock<IJob>();
job.Setup(j => j.Key).Returns(123);
var data = new MyJobData { Message = "test message", Priority = 1 };
// Act
await processor.ProcessJobAsync(jobClient.Object, job.Object, data, CancellationToken.None);
// Assert
mockZeebeService.Verify(x => x.CompleteJobAsync(
jobClient.Object,
job.Object.Key,
It.IsAny<object>()),
Times.Once);
}
}
🚀 Deployment
1. Build Release Version
dotnet build --configuration Release
2. Publish Self-Contained (Nếu cần)
dotnet publish --configuration Release --self-contained true --runtime win-x64
3. Docker (Nếu sử dụng)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyProject.csproj", "./"]
RUN dotnet restore "MyProject.csproj"
COPY . .
RUN dotnet build "MyProject.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.dll"]
🔍 Troubleshooting
Lỗi thường gặp:
"Could not load file or assembly 'Orchestrator.Library'"
- Kiểm tra file DLL có tồn tại không
- Kiểm tra target framework có tương thích không
"No service for type 'IZeebeService' has been registered"
- Đảm bảo đã gọi
services.AddZeebeService()
- Kiểm tra using statements
- Đảm bảo đã gọi
"Zeebe client connection failed"
- Kiểm tra Zeebe server có đang chạy không
- Kiểm tra connection string trong configuration
Debug Tips:
// Enable detailed logging
services.AddLogging(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
// Log service registrations
services.AddZeebeService(provider => CreateZeebeClient(provider), options =>
{
options.EnableDetailedLogging = true;
});
Product | Versions 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. |
-
net8.0
- Confluent.Kafka (>= 2.11.1)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.1)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
- zb-client (>= 2.9.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 3.0.0 - Performance Optimized:
- NEW: Complete Task.Run wrapper for all consumer loops to prevent main thread blocking
- NEW: Dual-level Task.Run optimization (consumer loop + message processing)
- NEW: Enhanced error isolation and parallel message processing
- IMPROVED: Maximum throughput with non-blocking consumer architecture
- IMPROVED: Better resource utilization and scalability
- IMPROVED: Consumer stability and reliability
- FIXED: Potential consumer hanging issues in high-load scenarios
Version 2.0.0 - Enhanced Framework:
- NEW: BaseJobProcessor with template method pattern for common workflow
- NEW: HttpJobProcessor for specialized HTTP request handling
- NEW: KafkaJobProcessor for Kafka message publishing patterns
- NEW: JobContext wrapper with rich job information and utilities
- NEW: WorkerConfiguration and WorkerFactory for streamlined setup
- NEW: EnhancedGenericWorker with automatic retry and error handling
- IMPROVED: Configuration-driven approach for workers and processors
- IMPROVED: Enhanced error handling with ECode mapping
- BREAKING: Simplified processor interfaces - legacy support available
- Examples and comprehensive documentation included