Documentation Index | API Reference (Wiki)
PosSharp is a platform-agnostic, reactive UPOS (Unified POS) framework for .NET. It provides a modern implementation of the UPOS standard, decoupling core POS logic from platform-specific SDK dependencies like the legacy POS for .NET (OPOS) or Windows-only components.
- Modern C# Implementation: Fully utilizes C# 12+ features (Primary Constructors, etc.) and targets
.net10.0. Supports older platforms via PolySharp. - Reactive State Management: Built-in state synchronization using R3. Properties like
State,PowerState, andResultCodeare exposed as reactive observables. - Mediator Architecture: Centralized "Single Source of Truth" via the Mediator pattern, ensuring all properties (
DataCount,IsOpen, etc.) stay perfectly in sync across asynchronous operations. - Task-Based Asynchronous API: Modern asynchronous implementation of standard UPOS operations (
OpenAsync,ClaimAsync,SetEnabledAsync). - Power Management: Comprehensive support for power reporting and state notifications (
PowerNotify) integrated directly into the base abstraction. - Lock-Free Thread-Safety: Optimized for high-concurrency environments using CAS (Compare-And-Swap) base atomic state management via
AtomicState<T>. - Zero Build Warnings: Maintained at the highest quality with 100% XML documentation and strict static analysis.
| Package | Description |
|---|---|
| PosSharp.Abstractions | Core interfaces, enums, and event records. Perfect for application-side dependencies. |
| PosSharp.Core | The engine. Includes base classes, lifecycle management, and reactive mediator. |
# To implement a device
dotnet add package PosSharp.Core
# For pure abstractions
dotnet add package PosSharp.AbstractionsPosSharp utilizes a sophisticated, layered architecture designed for maximum decoupling and testability.
The framework is divided into two primary layers to minimize application-side dependencies:
graph TD
subgraph Core ["PosSharp.Core (Implementations)"]
CoreLogic[Base Implementation]
MediatorImpl[UposMediator]
LifecycleLogic[Lifecycle Orchestration]
end
subgraph Abstractions ["PosSharp.Abstractions (Contracts)"]
Interfaces[IUposDevice / IUposMediator]
Reactive[Reactive Streams / R3]
Enums[Error Codes / Constants]
end
%% Dependency relationship
Core -.->|Depends on| Abstractions
%% Usage Patterns
App([Your Application]) -.->|Uses| Abstractions
Dev([Your Device]) -.->|Implements| Core
- PosSharp.Abstractions: Pure contracts and types. Applications only need to depend on this package to consume devices.
- PosSharp.Core: Reference implementations and engine logic. Required only when developing new device simulators.
Each device implementation leverages the following internal patterns for thread-safety and reactive consistency:
graph TD
Device[IUposDevice] --> Base[UposDeviceBase]
Base --> Mediator[UposMediator]
Base --> Lifecycle[UposLifecycleManager]
Mediator -- Syncs --> Props[Reactive Properties]
Mediator -- Pushes --> Events[Reactive Events]
Each device delegates its state and property management to a UposMediator, which leverages AtomicState<T> for lock-free state transitions.
To create a new UPOS device, simply inherit from UposDeviceBase:
using PosSharp.Abstractions;
using PosSharp.Core;
// Example implementation of a CashChanger
public class MyCashChanger : [UposDeviceBase](https://github.com/w-red/PosSharp/wiki/PosSharp.Core.UposDeviceBase)
{
// Override required abstract members
protected override Task OnOpenAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task OnCloseAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task OnClaimAsync(int timeout, CancellationToken ct) => Task.CompletedTask;
protected override Task OnReleaseAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task OnEnableAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task OnDisableAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task<string> OnCheckHealthAsync(HealthCheckLevel level, CancellationToken ct)
{
return Task.FromResult("Internal:OK");
}
protected override Task OnDirectIOAsync(int command, int data, object obj, CancellationToken ct) => Task.CompletedTask;
protected override Task OnClearInputAsync(CancellationToken ct) => Task.CompletedTask;
protected override Task OnClearOutputAsync(CancellationToken ct) => Task.CompletedTask;
// Use the protected helpers to update internal state
public void SimulateCashAdded()
{
// DataCount is automatically synchronized via the Mediator
UpdateDataCount(DataCount + 1);
}
}If you are just consuming a device (e.g., in a UI or business logic layer), you only need to depend on PosSharp.Abstractions and use the reactive interfaces:
using PosSharp.Abstractions;
using R3;
public class DeviceMonitor([IUposDevice](https://github.com/w-red/PosSharp/wiki/PosSharp.Abstractions.IUposDevice) device)
{
public void Initialize()
{
// React to state changes
device.State
.Subscribe(state => Console.WriteLine($"Device state: {state}"));
// Handle data events
device.DataEvents
.Subscribe(e => Console.WriteLine($"Data received: {e.Status}"));
}
public async Task StartAsync()
{
await device.OpenAsync();
await device.ClaimAsync(1000);
await device.SetEnabledAsync(true);
}
}PosSharp is built with testability in mind. It includes a comprehensive test suite and provides stubs to help you test your own implementations.
dotnet test- Documentation Pipeline Fixed: Resolved multiple CI/CD issues in the automated Wiki sync workflow (BOM removal, internal link extension stripping, recursive API doc processing).
- Improved Release Workflow: Fixed version parsing for manual triggers and GitHub Packages authentication.
- README Modernization: Added architecture diagrams, language switcher, and improved onboarding flow.
- Terminology Clarification: Replaced "client-side" with "application-side" to better reflect the framework's usage context.
This project is licensed under the MIT License. See the LICENSE file for details.