π Use Cases in Clean Architecture and ConnectSoft¶
ConnectSoft enables a wide spectrum of use cases β from clean architecture orchestration to template-based delivery of SaaS platforms and AI-enhanced services. This document covers how use cases are realized within Clean Architecture and provides applied examples using ConnectSoftβs platform ecosystem.
π§ What is a Use Case?¶
In Clean Architecture, a Use Case represents an application-specific workflow β encapsulating business logic that coordinates domain models and external interactions without embedding technical dependencies.
Info
In ConnectSoft, use cases sit at the Application Layer and are invoked by controllers, queues, or schedulers. They handle orchestration, enforce domain rules, and delegate to aggregates or services.
A use case:
- Encapsulates one business operation
- Coordinates repositories, domain models, and external systems
- Remains framework-agnostic and stateless
π± Design Principles for Use Cases¶
| Principle | Explanation |
|---|---|
| β Single Responsibility | Focus on a single business operation or flow |
| π Stateless | Avoid internal state to maximize reusability |
| π Orchestration | Coordinate aggregates, value objects, and services |
| π¦ DTO Usage | Use DTOs for all input/output to ensure separation |
| π Transaction Scope | Enforce transactional boundaries for domain operations |
π§ͺ Example: PlaceOrderUseCase¶
public class PlaceOrderUseCase
{
private readonly IOrderRepository _orderRepository;
private readonly IInventoryService _inventoryService;
private readonly INotificationService _notificationService;
private readonly IUnitOfWork _unitOfWork;
public PlaceOrderUseCase(
IOrderRepository orderRepository,
IInventoryService inventoryService,
INotificationService notificationService,
IUnitOfWork unitOfWork)
{
_orderRepository = orderRepository;
_inventoryService = inventoryService;
_notificationService = notificationService;
_unitOfWork = unitOfWork;
}
public async Task Execute(PlaceOrderDto input)
{
using (var transaction = _unitOfWork.BeginTransaction())
{
foreach (var item in input.Items)
{
if (!await _inventoryService.IsInStock(item.ProductId, item.Quantity))
{
throw new InvalidOperationException($"Product {item.ProductId} is out of stock.");
}
}
var order = new Order(input.CustomerId);
foreach (var item in input.Items)
{
order.AddItem(item.ProductId, item.Quantity);
}
_orderRepository.Add(order);
foreach (var item in input.Items)
{
await _inventoryService.ReserveStock(item.ProductId, item.Quantity);
}
await _notificationService.SendOrderConfirmation(input.CustomerId, order.Id);
transaction.Commit();
}
}
}
π Sequence: Place Order¶
sequenceDiagram
participant User
participant UseCase as PlaceOrderUseCase
participant Domain as OrderAggregate
participant Inventory as InventoryService
participant Notification as NotificationService
User->>UseCase: Submit Order
UseCase->>Domain: Create Order
UseCase->>Inventory: Reserve Stock
UseCase->>Notification: Send Confirmation
π Real-World Use Cases¶
π E-Commerce¶
- Use Case:
PlaceOrder - Workflow: Validate inventory β Create order β Update stock β Notify customer.
sequenceDiagram participant UI participant UseCase as PlaceOrderUseCase participant Order as OrderAggregate participant Inventory as InventoryService participant Notification as NotificationService UI->>UseCase: Submit Order UseCase->>Order: Validate + Create UseCase->>Inventory: Reserve Items UseCase->>Notification: Send EmailHold "Alt" / "Option" to enable pan & zoom
π₯ Healthcare¶
- Use Case:
ScheduleAppointment - Workflow: Check provider availability β Create appointment β Notify stakeholders.
sequenceDiagram participant User participant UseCase as ScheduleAppointmentUseCase participant Calendar as AppointmentAggregate participant Notification as NotificationService User->>UseCase: Request Slot UseCase->>Calendar: Reserve Time UseCase->>Notification: Confirm SlotHold "Alt" / "Option" to enable pan & zoom
π³ Finance¶
- Use Case:
TransferFunds - Workflow: Validate balance β Debit source β Credit target β Record transaction.
sequenceDiagram participant User participant UseCase as TransferFundsUseCase participant Account as AccountAggregate User->>UseCase: Transfer Request UseCase->>Account: Withdraw from Source UseCase->>Account: Deposit to TargetHold "Alt" / "Option" to enable pan & zoom
π€ AI¶
- Use Case:
RunSemanticInference - Workflow: Accept prompt β Generate result via AI β Save result for traceability.
sequenceDiagram participant Trigger participant UseCase as SemanticKernelUseCase participant Kernel as SemanticAgent participant Store as LogStore Trigger->>UseCase: Send Prompt UseCase->>Kernel: Generate Completion UseCase->>Store: Save ResultHold "Alt" / "Option" to enable pan & zoom
βοΈ DevOps¶
- Use Case:
DeployService - Workflow: Validate infrastructure β Provision cloud resources β Trigger CI/CD deploy.
sequenceDiagram participant CLI participant UseCase as DeploymentUseCase participant Pulumi as PulumiService participant CI as AzurePipelines CLI->>UseCase: Deploy Request UseCase->>Pulumi: Provision Resources UseCase->>CI: Push Build + DeployHold "Alt" / "Option" to enable pan & zoom
πΉ Best Practices for Use Cases¶
-
Keep Stateless
- Avoid storing state inside the use case class.
-
Use DTOs
- Encapsulate input/output in well-structured data contracts.
-
Enforce Business Rules via Domain
- Delegate validations and calculations to aggregates or domain services.
-
Define Transaction Scope
- Ensure that all actions inside a use case are part of a single transactional unit.
-
Write Tests for All Flows
- Unit test the use case logic and integration test real services with stubs/mocks.
-
Avoid Infrastructure Dependencies
- Use ports and abstractions to isolate framework interactions.
β Conclusion¶
Use cases are the critical bridge between business needs and system behavior. Within Clean Architecture, they enable strict separation of concerns, centralized workflow control, and clear interfaces for input and output.
At ConnectSoft, use cases are more than a pattern β they're a first-class citizen in our platform and templates. Every solution we offer ensures that your workflows are stateless, testable, and decoupled from infrastructure. Whether you are building a SaaS product, integrating an AI engine, or automating deployments, the use case layer is your safest and most scalable foundation.
By combining Clean Architecture with DDD, event-driven messaging, and modular templates, ConnectSoft ensures that use cases are:
- π§ Easy to implement
- π Easy to test and evolve
- π Isolated from volatile infrastructure concerns
- π Ready for production, at any scale
π References¶
- Clean Architecture in .NET
- ConnectSoft Microservice Template
- ConnectSoft SaaS Offerings
- Domain-Driven Hexagon Architecture
- Use Cases in Software Design
Explore more in Clean Architecture and Microservice Template Use Cases.