Enterprise-Grade Engineering, Not Just a Hackathon Project
SOLID principles, MVVM architecture, dependency injection, automated CI/CD, comprehensive testing, DPAPI-encrypted security — every best practice, implemented rigorously.
SOLID Principles,
Not Just Buzzwords
Every class, every interface, every dependency follows proven software engineering principles. This is production-grade architecture built for maintainability, testability, and extensibility.
- SSingle Responsibility
Each class has one job — FileOperationService handles moves, RuleService handles rules.
- OOpen/Closed
Add new AI providers without modifying existing code.
- LLiskov Substitution
All 5 AI providers are interchangeable at runtime.
- IInterface Segregation
Focused interfaces — ViewModels only inject what they need.
- DDependency Inversion
All services wired through DI container abstractions.
// Dependency Injection — every service
// is injectable, mockable, replaceable
services.AddSingleton<IAiService, AiService>();
services.AddSingleton<IRuleService, RuleService>();
services.AddSingleton<IHistoryService, HistoryService>();
services.AddSingleton<ICredentialService,
CredentialService>();
// AI Providers (Strategy Pattern)
services.AddSingleton<GeminiProviderService>();
services.AddSingleton<GroqProviderService>();
services.AddSingleton<OpenAiProviderService>();
services.AddSingleton<AnthropicProviderService>();
services.AddSingleton<OllamaProviderService>();
// ViewModels — Transient for fresh state
services.AddTransient<DropZoneViewModel>();
services.AddTransient<RulesManagerViewModel>();
services.AddTransient<SettingsViewModel>();Presentation Layer
Service Layer
Data Layer
Dependencies flow upward through interfaces
Clean Three-Layer
Architecture
Strict separation of concerns — Views never touch services, ViewModels never touch Views. Each layer communicates only through well-defined interfaces. The result: any layer can be replaced or tested independently.
- Views bind to ViewModels via XAML data binding
- ViewModels consume services through constructor injection
- Services access data through IStorageService abstraction
5 design patterns, one clean codebase
Every pattern solves a real problem in AutoDrop — from hot-swapping AI providers to full undo history. No academic fluff, just production code.
Strategy Pattern
Switch between 5 AI providers at runtime without changing a single line of calling code.
- Runtime provider selection via settings
- Zero code changes when adding providers
- Shared base class (Template Method)
provider = settings.Provider switch {
Gemini => _geminiService,
Groq => _groqService,
OpenAI => _openAiService,
Claude => _anthropicService,
Ollama => _ollamaService,
};Template Method
Shared behavior in AiProviderBase — prompt building, JSON parsing, and error handling.
- DRY across all 5 providers
- Override only what differs per provider
- Centralized error handling logic
abstract class AiProviderBase {
protected string BuildPrompt();
protected AiResult ParseJson();
abstract Task<string>
SendRequestAsync(object req);
}MVVM Pattern
Views (XAML) bind to ViewModels (C#) which consume Services. Zero code-behind.
- Auto-generated change notifications
- Auto-generated ICommand bindings
- No code-behind — pure data binding
[ObservableProperty]
private bool _isDragOver;
[RelayCommand]
async Task HandleDropAsync(
string[] paths) =>
await _aiService.AnalyzeFileAsync(paths[0]);Command Pattern
Every file operation is an undoable command — reversed with a single click.
- Full operation history with timestamps
- Single and bulk undo support
- Persists across application restarts
public class MoveOperation {
string SourcePath { get; set; }
string DestPath { get; set; }
DateTime Timestamp { get; set; }
void Undo() =>
File.Move(DestPath, SourcePath);
}Repository Pattern
Abstract data storage behind IStorageService. Swap JSON for SQLite seamlessly.
- Interface-based storage abstraction
- JSON serialization with validation
- Thread-safe with SemaphoreSlim
interface IStorageService {
Task<T> LoadAsync<T>(string key);
Task SaveAsync<T>(string key, T val);
}
var settings = await _storage
.LoadAsync<AiSettings>("ai_config");
CI/CD Pipeline
One command releases to production. Push a tag, and GitHub Actions builds, tests, packages, and publishes — automatically.
Pipeline Config
Trigger: push, PR, tags (v*.*.*)
Runner: windows-latest
Parallel: 3 architectures
Auto-detect: stable vs pre-release
Time: ~5 min (was 30 min manual)
Artifacts: .exe + ZIP per arch
Automated triggers
The pipeline triggers on every push and pull request. Tag-based releases (v*.*.*) automatically create GitHub Releases with installers and ZIP archives for all architectures.
- Push to main/develop/feature branches runs build + test.
- Pull requests run full CI before merge is allowed.
- Semantic version tags (v1.0.0) trigger release pipeline.
Build & test
Every commit is compiled in Release configuration and tested before any artifact is produced. Warnings are treated as errors — no silent issues in production.
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- run: dotnet restore
- run: dotnet build --configuration Release
--warnaserror
- run: dotnet test --no-build
--verbosity normalMulti-architecture publishing
Three architectures are built in parallel using a GitHub Actions matrix strategy. Each produces a self-contained, single-file executable with no runtime dependencies.
- win-x64 — Intel/AMD 64-bit (~85% of Windows PCs)
- win-x86 — Legacy 32-bit system support
- win-arm64 — Surface Pro X, ARM laptops
strategy:
matrix:
runtime: [win-x64, win-x86, win-arm64]
steps:
- run: dotnet publish AutoDrop.csproj
--self-contained true
-p:PublishSingleFile=true
-p:EnableCompressionInSingleFile=true
--runtime ${{ matrix.runtime }}
--output ./publish/${{ matrix.runtime }}Automated release
Tagged commits automatically create a GitHub Release. The pipeline detects whether it is a stable release (v1.0.0) or a pre-release (v1.0.0-beta.1) and labels it accordingly. All architecture ZIPs and the Inno Setup installer are attached as release assets.
- Builds 3 architectures in parallel
- Runs the complete test suite
- Creates the GitHub Release automatically
- Uploads all artifacts as release assets
- Labels stable vs pre-release versions
Tested, validated, production-ready
xUnit with FluentAssertions and Moq. Every service is interface-based and fully mockable. Tests run on every push and before every release.
RuleService
UnitExtension matching, rule CRUD, usage tracking, conflict resolution
FileOperationService
Unit + IntegrationMove/copy, auto-rename, collision handling, directory creation
DuplicateDetection
UnitSHA-256 hashing, size-only fallback, large file handling
UndoService
UnitOperation history, single/bulk undo, persistence across restarts
StorageService
IntegrationJSON read/write, schema validation, concurrent access
AI Providers
Unit + MockProvider switching, JSON parsing, error handling, timeout recovery
Production hardening checklist
IDisposable
All services with cleanup logic implement IDisposable. Event handlers unsubscribed, streams closed.
ConfigureAwait(false)
Every async call in the service layer avoids deadlocks and improves non-UI thread performance.
CancellationToken
All async interfaces accept CancellationToken. Operations can be gracefully cancelled.
Null Safety
C# nullable reference types enabled project-wide. Compiler catches null issues at build time.
Thread Safety
SemaphoreSlim guards all file write operations. Only one thread modifies state at a time.
Structured Logging
Serilog with rolling daily logs, 7-day retention. Debug in dev, Info in release.
Security-first,
not an afterthought
From DPAPI-encrypted API keys to zero telemetry — security is built into the architecture, not bolted on. Your files, your data, your control.
- Windows DPAPI Encryption
API keys encrypted with Windows Data Protection API — tied to your Windows account. Cannot be decrypted on other machines.
- Zero Plaintext Storage
Credentials stored in %AppData%\AutoDrop\Credentials\. Even if copied, useless without your login.
- Zero Telemetry
No usage data, no analytics, no crash reports. File paths and content never leave your machine.
- Local AI by Default
Built-in ONNX model runs 100% offline. No API keys needed. Your data stays local.
- Input Validation
All model setters validate with ArgumentException. File imports capped at 10MB. Rules JSON validated on load.
- Disclaimer-Gated Cloud AI
Users must explicitly accept a disclaimer before enabling cloud providers. No silent uploads.
Professional-grade distribution
A polished installer, self-contained executables, and multi-architecture support — users download, run, and it just works.
Inno Setup 6 Professional Installer
- Modern Windows 11 style wizard
- Per-user install to %LocalAppData% (no admin)
- Desktop shortcut + Start menu entry
- Clean uninstaller removes all files
- License agreement screen
Self-Contained Deployment
- Single .exe file (~75MB, compressed)
- .NET 8 runtime bundled — works on any PC
- No prerequisites, no runtime installs
- EnableCompressionInSingleFile for size
- IncludeNativeLibrariesForSelfExtract
Multi-Architecture Support
- win-x64 — Intel/AMD 64-bit (~85% market)
- win-x86 — Legacy 32-bit systems
- win-arm64 — Surface Pro X, ARM devices
- All 3 built in parallel via matrix
- Separate ZIP per arch on GitHub Releases

