Skip to content

Repository files navigation

PosSharp

PosSharp Logo

English | ζ—₯本θͺž


Documentation Index | API Reference (Wiki)

License: MIT .NET Core NuGet Core NuGet Abstractions CI CD

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.

πŸš€ Key Features

  • 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, and ResultCode are 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.

πŸ“¦ Packages

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.

Installation

# To implement a device
dotnet add package PosSharp.Core

# For pure abstractions
dotnet add package PosSharp.Abstractions

πŸ—οΈ Architecture

PosSharp utilizes a sophisticated, layered architecture designed for maximum decoupling and testability.

Package Architecture

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
Loading
  • 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.

Internal Component Structure

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]
Loading

Mediator-Based State Management

Each device delegates its state and property management to a UposMediator, which leverages AtomicState<T> for lock-free state transitions.

πŸ› οΈ Usage

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);
    }
}

Consuming a Device (Application-Side)

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);
    }
}

πŸ§ͺ Testing

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

✨ What's New in v1.2.1

  • 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.

Read the full CHANGELOG

πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.

About

modern, platform-agnostic UPOS (UnifiedPOS) framework for .NET, featuring R3-driven reactive state management.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages