3.6 KiB
3.6 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
- User configures paths/settings in the UI (
DataModel.cs— MVVM ViewModel) ProcessImagesCommandtriggersImageCreationServiceImageCreationServiceprocesses files in parallel chunks, with configurable concurrency and batch size (GC flush between chunks)- Each file is handled by the ImageSharp
IImageCreatorimplementation - Output: resized/watermarked/overlaid images written to a destination folder hierarchy
Key Abstractions (MaddoShared)
IImageCreator— single async method to process one image; implemented byImageCreatorImageSharp(SixLabors.ImageSharp)ImageCreationService— parallel orchestrator; usesAsyncEnumeratorwith chunking; loads logo once, clones per thread for thread safetyImageState— 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)FileHelperSharp— recursive file enumeration with folder-per-N-files mapping and counter formatting
Conventions
C# Style
- File-scoped namespaces everywhere:
namespace MaddoShared; - Nullable reference types enabled (
<Nullable>enable</Nullable>) - Implicit usings enabled
ConfigureAwait(false)on allawaitcalls in library code
Dependency Injection
- Constructor injection throughout; loggers typed as
ILogger<T> - Main app wires services in
Program.csviaIServiceCollection
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 ImageCreationServiceuses configurableMaxDegreeOfParallelismandChunkSize; explicitGC.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 (seeNuGet.Config)