This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Restore, build, and test (standard workflow)
dotnet restore
dotnet build
dotnet test
# Run a single test
dotnet test --filter "FullyQualifiedName~TestMethodName"
# Build specific configuration
dotnet build -c ReleaseThis is a .NET library (ktsu.AppDataStorage) for persistent application data storage with JSON serialization. The solution uses:
- ktsu.Sdk - Custom SDK providing shared build configuration
- MSTest.Sdk - Test project SDK with Microsoft Testing Platform
- Multi-targeting: net10.0, net9.0, net8.0, net7.0, netstandard2.0, netstandard2.1
AppDataStorage/AppData.cs- Single source file containing all library code:AppDatastatic class - Helper methods for file operations, JSON serialization configAppData<T>generic abstract class - Base class for app data types with save/load functionality
System.IO.Abstractions- File system abstraction for testabilityktsu.Semantics.Paths- Strongly-typed path classes (AbsoluteFilePath,RelativeDirectoryPath,FileName)ktsu.CaseConverter- Snake_case conversion for file namingktsu.RoundTripStringJsonConverter- JSON serialization supportPolyfill- ProvidesEnsureclass for argument validation (e.g.,Ensure.NotNull())
Users create a class inheriting from AppData<T> to store application settings:
public class MyAppData : AppData<MyAppData>
{
public string Setting { get; set; } = "default";
}
// Load or create, then use static accessor
var data = MyAppData.LoadOrCreate();
var same = MyAppData.Get(); // Singleton-like access
data.Save();- Files stored in
%APPDATA%/{AppDomain.FriendlyName}/as{class_name_snake_case}.json - Thread-safe with lock objects (uses
Locktype on .NET 9+,objecton earlier versions) - Debounced saves via
QueueSave()/SaveIfRequired()(3-second debounce) - Automatic backup files (
.bksuffix) with timestamped collision handling - Safe write pattern: write to
.tmp, backup existing, move.tmpto final - Lazy singleton access via
Get()backed byLazy<T> LoadOrCreate()overloads support custom subdirectories and file names- Corrupt file recovery: falls back to
.bkbackup, then creates a fresh instance - Process exit handler ensures queued saves are flushed via
IDisposable
Tests use MockFileSystem from System.IO.Abstractions.TestingHelpers with thread-local isolation:
// In ClassInitialize - set up factory (each thread gets its own MockFileSystem)
AppData.ConfigureForTesting(() => new MockFileSystem());
// In TestInitialize - clear cached instance for test isolation
AppData.ClearCachedFileSystem();
// In cleanup
AppData.ResetFileSystem();Tests run with [Parallelize(Scope = ExecutionScope.MethodLevel)] for parallel execution. Tests using the shared singleton (Get()) must be marked [DoNotParallelize].
Uses scripts/PSBuild.psm1 PowerShell module for CI pipeline. Version increments are controlled by commit message tags: [major], [minor], [patch], [pre].
Do not add global suppressions for warnings. Use explicit suppression attributes with justifications when needed, with preprocessor defines only as fallback. Make the smallest, most targeted suppressions possible.