Catalog/.github/copilot-instructions.md
MaddoScientisto d6b778a648 Refactor application to remove Windows Forms dependencies and transition to Avalonia UI
- Deleted MainWindow.xaml.cs, which contained the WPF implementation of the main window.
- Updated Program.cs to remove Windows Forms initialization and support only Avalonia UI.
- Removed Windows Forms specific code from ViewModelBase, including control marshalling logic.
2026-05-09 14:04:21 +02:00

3.9 KiB

Copilot Instructions

Build & Test Commands

# Build
dotnet build Catalog.slnx

# Run all tests
dotnet test MaddoShared.Tests

# Run a single test
dotnet test MaddoShared.Tests --filter "FullyQualifiedName~MethodName"

# Benchmarks (modes: quick | all | parallel | chunks | sizes | stress)
.\run-benchmarks.ps1 quick

# Publish release build (self-contained Windows EXE)
dotnet publish "imagecatalog\ImageCatalog 2.csproj" -c Release -r win-x64 --self-contained

Architecture

This is an Avalonia image cataloging application targeting .NET 10.0-windows.

Projects

Project Purpose
imagecatalog Main desktop application — Avalonia with Fluent theme (AvaloniaMainWindow)
MaddoShared Shared image processing library (the core)
MaddoShared.Tests Unit tests for MaddoShared
MaddoShared.Benchmarks BenchmarkDotNet performance benchmarks
WPFCatalog Alternate WPF UI (secondary)
ImageCatalogCS / ImageCatalogParallel Legacy/experimental variants
CatalogLib / CatalogLibVb / CatalogVbLib Legacy VB.NET libraries

The main app launches Avalonia directly. Dialog events (SelectSourceFolderRequested, etc.) are subscribed in AvaloniaMainWindow code-behind. DataModel.UiInvoker must be set by the active UI to enable cross-thread UI updates (Avalonia sets this to Dispatcher.UIThread.Invoke).

Core Flow

  1. User configures paths/settings in the UI (DataModel.cs — MVVM ViewModel)
  2. ProcessImagesCommand triggers ImageCreationService
  3. ImageCreationService processes files in parallel chunks, with configurable concurrency and batch size (GC flush between chunks)
  4. Each file is handled by an IImageCreator implementation (GDI+ or ImageSharp)
  5. Output: resized/watermarked/overlaid images written to a destination folder hierarchy

Key Abstractions (MaddoShared)

  • IImageCreator — single async method to process one image; two implementations: ImageCreatorGDI (System.Drawing) and ImageCreatorSharp (SixLabors.ImageSharp)
  • ImageCreationService — parallel orchestrator; uses AsyncEnumerator with chunking; loads logo once, clones per thread for thread safety
  • ImageState — per-file processing context (input path, EXIF orientation, thumbnail sizes, overlays, logo, rotation)
  • PicSettings — 50+ property configuration model (dimensions, fonts, colors, JPEG quality, watermark, logo positioning, ImageCreatorProvider selector)
  • FileHelperSharp — recursive file enumeration with folder-per-N-files mapping and counter formatting

Implementation Selection

PicSettings.ImageCreatorProvider switches between "Sharp" (SixLabors.ImageSharp) and "Alternate" (GDI+) at runtime.

Conventions

C# Style

  • File-scoped namespaces everywhere: namespace MaddoShared;
  • Nullable reference types enabled (<Nullable>enable</Nullable>)
  • Implicit usings enabled
  • ConfigureAwait(false) on all await calls in library code

Dependency Injection

  • Constructor injection throughout; loggers typed as ILogger<T>
  • Main app wires services in Program.cs via IServiceCollection

Testing

  • MSTest with [TestClass] / [TestMethod]
  • FluentAssertions for assertions
  • Moq for mocking
  • Factory helper pattern in tests: CreateService(Action<Config> configure = null) methods for flexible test setup

Async / Parallelism

  • All image I/O is async Task
  • ImageCreationService uses configurable MaxDegreeOfParallelism and ChunkSize; explicit GC.Collect() between chunks to manage memory under batch load

Versioning & CI

  • Semantic versioning via GitVersion (mode: ContinuousDelivery, current base: 3.2.0)
  • GitLab CI pipeline: builds → single-file self-contained EXE → GitLab Release
  • Private NuGet packages scoped to AIFotoONLUS.* prefix, routed to the GitLab package registry (see NuGet.Config)