Beep.Skia layer architecture: hosts, DrawingManager, components, connections and services

The diagram above was drawn with Beep.Skia itself: the generator loads it as a normal component graph and renders it through DrawingManager.Draw.

Solution Structure

The Beep.Skia solution is composed of 17 modular projects, each with a well-defined responsibility. This separation ensures maintainability, testability, and allows consumers to reference only the packages they need.

# Project Layer Description
1 Beep.Skia Core Shared abstractions, base classes, interfaces, and the central SkiaComponent model
2 Beep.Skia.Model Model Domain models, data structures, diagram entity definitions, and serialization contracts
3 Beep.Skia.Domain Domain Business logic, diagram operations, validation rules, and domain services
4 Beep.Skia.Infrastructure Infrastructure Persistence, file I/O, logging, and cross-cutting concerns
5 Beep.Skia.Canvas Core Rendering surface, viewport management, zoom/pan, and SkiaSharp canvas abstraction
6 Beep.Skia.Nodes Core All node types across 18 diagram families, hit testing, and per-node rendering
7 Beep.Skia.Connections Core Connection lines, routing algorithms, port management, and arrowhead rendering
8 Beep.Skia.Serialization Core JSON and binary diagram serialization, version migration, and export formats
9 Beep.Skia.Theming Core Material Design 3.0 theme engine, color palettes, typography, and style tokens
10 Beep.Skia.Workflow Core Workflow automation engine, action execution, conditional branching, and state management
11 Beep.Skia.Editor Presentation Visual diagram editor host, toolbars, property grids, and toolbox integration
12 Beep.Skia.Controls Presentation 60+ reusable UI controls including property editors, color pickers, and mini-maps
13 Beep.Skia.Host Host Application shell, window management, menu systems, and startup configuration
14 Beep.Skia.Demo Host Demonstration and sample application showcasing all diagram families and features
15 Beep.Skia.Tests Infrastructure Unit tests, integration tests, and rendering verification
16 Beep.Skia.Benchmarks Infrastructure Performance benchmarks for rendering, hit testing, and serialization
17 Beep.Skia.Extensions Core Extension methods, utility classes, and shared helpers across all projects

Layered Architecture

Beep.Skia follows a strict layered architecture where dependencies flow in one direction: from the Host layer down through Presentation, Core, Domain, and Model, terminating at Infrastructure. This design enforces separation of concerns and prevents circular dependencies.

Layer Projects Responsibility
Host Beep.Skia.Host, Beep.Skia.Demo Application entry points, shell configuration, DI container setup, and platform-specific hosting. Depends on Presentation and Core layers.
Presentation Beep.Skia.Editor, Beep.Skia.Controls User interface components, visual editors, toolbars, property grids, and interactive controls. Depends on Core and Domain layers.
Core Beep.Skia, Beep.Skia.Canvas, Beep.Skia.Nodes, Beep.Skia.Connections, Beep.Skia.Serialization, Beep.Skia.Theming, Beep.Skia.Workflow, Beep.Skia.Extensions Framework engine: rendering pipeline, node model, connection routing, serialization, theming, and workflow execution. Depends on Domain and Model layers.
Domain Beep.Skia.Domain Business rules, diagram operations, validation logic, and domain services. Depends on Model layer.
Model Beep.Skia.Model Pure data objects, entity definitions, enums, and serialization contracts. Has no project dependencies.
Infrastructure Beep.Skia.Infrastructure, Beep.Skia.Tests, Beep.Skia.Benchmarks Persistence, logging, cross-cutting concerns, tests, and benchmarks. Depends on Core and Domain layers.

The dependency rule ensures that inner layers (Model, Domain) have no knowledge of outer layers (Presentation, Host). This allows the core framework to be used in any .NET application regardless of the UI technology.

Key Design Patterns

Pattern Usage in Beep.Skia
Composite SkiaComponent serves as the base for all visual elements; components can contain child components forming a hierarchical tree. The canvas renders the entire component graph recursively.
Strategy Connection routing algorithms (Straight, Orthogonal, Curved) are swappable per connection through LineRoutingMode.
Observer Canvas invalidation and property change notifications propagate through the component tree. Nodes notify the drawing manager of position, size, and state changes.
Command Diagram mutations (add, remove, move, resize, connect, disconnect) are encapsulated as DrawingAction objects, enabling undo/redo through HistoryManager.
Data Transfer Object Serialization converts the live graph into plain DTOs. DrawingManager.ToDto() produces a DiagramDto of ComponentDto and LineDto records, and LoadFromDto() restores it.
Factory SkiaComponentRegistry creates component instances from discovered type definitions (AssemblyClassDefinition), powering the palette and template loading.
Decorator Visual decorators (selection handles, resize grips, connection ports) wrap base components without modifying their core behavior.
Mediator DrawingManager acts as the central mediator, coordinating interactions between nodes, connections, the canvas, and input events.

Target Frameworks

Beep.Skia targets modern .NET runtimes with cross-platform support:

Framework Platforms Notes
.NET 8 Windows, Linux, macOS Long-term support (LTS) release. Recommended for production deployments.
.NET 9 Windows, Linux, macOS Standard-term support (STS) release. Includes latest performance improvements in SkiaSharp integration.

All projects in the solution support both net8.0 and net9.0 target framework monikers. The framework is compatible with Windows Forms, WPF, MAUI, Avalonia, and Blazor Hybrid hosting models.

Project Dependency Graph

The dependency graph follows a clean layered structure. Top-level projects depend on lower-level projects; no circular dependencies exist.

Project Depends On
Beep.Skia.Model (none — leaf project)
Beep.Skia.Domain Beep.Skia.Model
Beep.Skia.Extensions Beep.Skia.Model
Beep.Skia Beep.Skia.Model, Beep.Skia.Domain, Beep.Skia.Extensions
Beep.Skia.Canvas Beep.Skia
Beep.Skia.Nodes Beep.Skia, Beep.Skia.Canvas
Beep.Skia.Connections Beep.Skia, Beep.Skia.Canvas
Beep.Skia.Theming Beep.Skia
Beep.Skia.Serialization Beep.Skia, Beep.Skia.Model
Beep.Skia.Workflow Beep.Skia, Beep.Skia.Domain
Beep.Skia.Controls Beep.Skia, Beep.Skia.Theming
Beep.Skia.Editor Beep.Skia, Beep.Skia.Nodes, Beep.Skia.Connections, Beep.Skia.Controls, Beep.Skia.Theming, Beep.Skia.Serialization
Beep.Skia.Infrastructure Beep.Skia, Beep.Skia.Domain
Beep.Skia.Host Beep.Skia.Editor, Beep.Skia.Infrastructure
Beep.Skia.Demo Beep.Skia.Host, Beep.Skia.Editor, Beep.Skia.Nodes, Beep.Skia.Theming
Beep.Skia.Tests Beep.Skia, Beep.Skia.Nodes, Beep.Skia.Connections, Beep.Skia.Serialization, Beep.Skia.Domain
Beep.Skia.Benchmarks Beep.Skia, Beep.Skia.Nodes, Beep.Skia.Canvas, Beep.Skia.Connections

This dependency design ensures that the core rendering engine (Beep.Skia, Beep.Skia.Canvas, Beep.Skia.Nodes) can be used independently of the editor host, making it suitable for embedding in lightweight applications or server-side diagram generation scenarios.