Files
AmiReel/.github/instructions/design-principles.instructions.md
klevze 603af17e56 Remove legacy WPF app, flatten WinUI project to repo root, rename namespace
The repo carried two parallel UIs (WPF + WinUI) sharing Models/Services via
cross-directory Link includes. Now that WinUI is the only frontend, collapse
the structure so the WinUI project IS the repo root instead of a nested
sibling folder:

- Delete the WPF project entirely (App.xaml, MainWindow.xaml, csproj) and its
  bin/obj output
- Move AmiReel.WinUI/* up to the repo root (App, MainWindow, MainPage,
  DialogHelper, Assets, Package.appxmanifest, app.manifest, Properties,
  .github/instructions, AGENTS.md) via git mv, preserving history
- Rename AmiReel.WinUI.csproj -> AmiReel.csproj; regenerate the solution as
  AmiReel.slnx (the newer XML solution format) with a single project
- Rename namespace AmigaDB.VideoRenderer.{Models,Services} -> AmiReel.{...}
  and AmiReel_WinUI -> AmiReel across all files, including the embedded
  ffmpeg/ffprobe resource logical names in the csproj and ToolExtractor
- Models/ and Services/ no longer need the Link-based cross-directory
  <Compile Include>; they're picked up by the SDK's default globbing now
  that they live under the project directory
- Rename assets/ -> branding/ (source icon art) to avoid a case-insensitive
  collision with Assets/ (packaged tile art) once both sit at repo root
- Merge the two .gitignore files into one; track the PublishProfiles pubxml
  files instead of ignoring them (no secrets, and they keep publish
  reproducible across machines) as branding, gitignore, etc.
- Simplify publish-win-x64.ps1 (drop the -Target Wpf/WinUI switch, there's
  only one target now) and rewrite README.md to describe the single-project
  layout, build/run/publish commands, and file structure

Verified: dotnet build succeeds for both AmiReel.csproj and AmiReel.slnx, and
the built exe launches and renders identically to before the move.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 14:07:10 +02:00

5.8 KiB

description, applyTo
description applyTo
Design principles (DRY, KISS, SOLID, YAGNI) enforced in every code change **/*.cs, **/*.xaml

Design Principles

Apply these principles in every change you make to this codebase. When in doubt, favour simplicity and clarity over cleverness.


1. DRY — Don't Repeat Yourself

"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."

Rules

  • Before writing new code, search the codebase for existing implementations that solve the same problem.
  • Extract shared logic into helper methods, base classes, or services.
  • If you find duplicated code during a task, refactor it as part of the same change.
  • Prefer generic/reusable components over copy-paste variations.

Anti-patterns to avoid

  • Copy-pasting code between classes/files instead of extracting a shared method.
  • Creating multiple converters/helpers that do the same thing.
  • Duplicating validation logic across ViewModel and Model layers.

2. KISS — Keep It Simple, Stupid

"Simplicity is the ultimate sophistication."

Rules

  • Choose the simplest approach that meets the requirement.
  • Avoid unnecessary abstractions, inheritance hierarchies, or patterns that add complexity without clear benefit.
  • Write code that reads like plain English — favour descriptive names over comments.
  • If a method is longer than ~30 lines, consider splitting it.
  • If a class does more than one thing, split it (see SRP below).

Anti-patterns to avoid

  • Over-engineering with factories/builders/strategies for simple object creation.
  • Creating deep inheritance trees when composition would suffice.
  • Using complex LINQ chains when a simple foreach is clearer.

3. SOLID Principles

3.1 SRP — Single Responsibility Principle

"A class should have only one reason to change."

  • Each class/file should have one clear responsibility.
  • ViewModels handle UI state & commands. Services handle business logic. Models hold data.
  • If a class name contains "And" or "Manager", it likely violates SRP.

3.2 OCP — Open/Closed Principle

"Software entities should be open for extension, but closed for modification."

  • Use interfaces and abstract classes so behaviour can be extended without modifying existing code.
  • Prefer adding new implementations over modifying existing ones.
  • Use dependency injection to swap implementations.

3.3 LSP — Liskov Substitution Principle

"Objects of a superclass should be replaceable with objects of its subclasses without altering correctness."

  • Derived classes must honour the contracts of their base classes.
  • Never throw NotImplementedException in overridden methods — if a subclass can't fulfil the contract, the inheritance is wrong.

3.4 ISP — Interface Segregation Principle

"No client should be forced to depend on methods it does not use."

  • Keep interfaces small and focused.
  • Prefer multiple small interfaces over one large one.
  • Example: INavigationService, IDialogService, ISettingsService — not IAppService.

3.5 DIP — Dependency Inversion Principle

"Depend upon abstractions, not concretions."

  • High-level modules must not depend on low-level modules. Both should depend on abstractions.
  • Use constructor injection for dependencies.
  • Register services in a DI container (e.g., Microsoft.Extensions.DependencyInjection).

4. YAGNI — You Aren't Gonna Need It

"Don't add functionality until it is necessary."

Rules

  • Only implement what is explicitly requested or clearly needed right now.
  • Do not add "just in case" parameters, methods, or abstractions.
  • If you're unsure whether something is needed, leave it out — it can always be added later.

Anti-patterns to avoid

  • Adding unused interface methods "for future use".
  • Building a generic framework when a single concrete class suffices.
  • Creating configuration options nobody has asked for.

Quick Reference Checklist

Before submitting any code change, verify:

  • No duplicated code exists (DRY)
  • The solution is as simple as possible (KISS)
  • Each class has one responsibility (SRP)
  • New behaviour is added via extension, not modification (OCP)
  • Derived types can substitute their base types (LSP)
  • Interfaces are small and focused (ISP)
  • Dependencies point toward abstractions (DIP)
  • No speculative features were added (YAGNI)

Validation

  • Review every new/changed class for SRP violations — ask "does this class have more than one reason to change?"
  • Search the codebase for duplicate logic before adding new helpers: grep_search for similar method names or patterns.
  • Verify no speculative code was added — every line must trace back to the original request.
  • Build & register the MSIX package — see Build, Run & Deploy in .github/agents/Agents.md.

Must Read & Research

Agent Rule: Before making any code change related to design principles, you must fetch and review the relevant references below using fetch_webpage. Apply what you learn — do not skip this step.

# Reference When to consult
1 SOLID Principles in C# — Microsoft Learn Adding/refactoring classes, interfaces, or inheritance
2 .NET Design Guidelines Designing public APIs, naming, type design
3 Framework Design Guidelines (Book) Deep-dive on member design, exception patterns, collections
4 Clean Code Summary Code readability, function size, naming clarity