using DataArc.OrchestratR;
using DataArc.OrchestratR.Abstractions;
using Microsoft.Extensions.DependencyInjection;
// ============================================================
// Business Service Layer
// ============================================================
public interface IOrderService
{
Task<OrderDetailsDto> CreateOrderAsync(int productId, int quantity);
}
public class OrderService : IOrderService
{
public async Task<OrderDetailsDto> CreateOrderAsync(int productId, int quantity)
{
await Task.Delay(10); // Simulated logic
return new OrderDetailsDto { OrderId = 123, ProductId = productId, Quantity = quantity, Success = true };
}
}
// ============================================================
// Orchestrators
// ============================================================
// Input-only orchestrator
public class CreateOrderOrchestrator(IOrderService orderService)
: Orchestrator<CreateOrderInputOnly>
{
public override async Task ExecuteAsync(CreateOrderInputOnly input)
{
await orderService.CreateOrderAsync(input.ProductId, input.Quantity);
Console.WriteLine("Order created successfully (input-only)");
}
}
// Input + Output orchestrator
public class CreateOrderOrchestratorWithOutput(IOrderService orderService)
: Orchestrator<CreateOrderInput, CreateOrderOutput>
{
public override async Task<CreateOrderOutput> ExecuteAsync(CreateOrderInput input, CreateOrderOutput output)
{
var result = await orderService.CreateOrderAsync(input.ProductId, input.Quantity);
return new CreateOrderOutput { OrderDetails = result };
}
}
// ============================================================
// Contracts (IO Models)
// ============================================================
public record CreateOrderInputOnly(int ProductId, int Quantity) : IOrchestratorInput;
public record CreateOrderInput(int ProductId, int Quantity) : IOrchestratorInput;
public class CreateOrderOutput : IOrchestratorOutput
{
public OrderDetailsDto? OrderDetails { get; set; }
}
public class OrderDetailsDto
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Success { get; set; }
}
// ============================================================
// Console Entry Point
// ============================================================
internal class Program
{
private static async Task Main()
{
var serviceProvider = new ServiceCollection()
.AddScoped<IOrderService, OrderService>()
.AddDataArcOrchestration(options =>
{
options.AddOrchestrator<CreateOrderOrchestrator>();
options.AddOrchestrator<CreateOrderOrchestratorWithOutput>();
})
.BuildServiceProvider();
var handler = serviceProvider.GetRequiredService<IOrchestratorHandler>();
// Fire-and-forget
await handler.OrchestrateAsync<CreateOrderOrchestrator>(new CreateOrderInputOnly(1, 10));
// Input + Output
var result = await handler.OrchestrateAsync<CreateOrderOrchestratorWithOutput, CreateOrderOutput>(
new CreateOrderInput(1, 10), new CreateOrderOutput());
if (result?.OrderDetails != null)
{
Console.WriteLine($"Order Id: {result.OrderDetails.OrderId},
Product: {result.OrderDetails.ProductId},
Quantity: {result.OrderDetails.Quantity}");
}
Console.WriteLine("Complete...");
Console.ReadKey();
}
}