Skip to content

Layered Dependency Rules

tonythethompson edited this page Jul 28, 2026 · 3 revisions

Layered Dependency Rules

Trackdub enforces a unidirectional dependency graph so Domain stays free of frameworks and UI. UI never owns persistence or inference.

Product dependency direction

App.Avalonia → Application, Composition, Domain, Licensing, Media.Playback, Sdk
App.Avalonia.Tests → Application, Composition, Contracts, Domain, Licensing (+ App source links)
UI.Tests → App.Avalonia

Application → Contracts, Domain, Licensing
Infrastructure → Application, Contracts, Domain
Media → Application, Analyzers, Contracts, Domain
Media.Playback → Application, Domain
Inference → Contracts, Domain
Inference.Onnx → Inference, Contracts, Domain
Composition → Application, Inference, Inference.Onnx, Infrastructure, Licensing, Media, Media.Playback
Sdk → Application, Composition, Licensing
Cli → Sdk
DubBench → Benchmarks, Domain, Inference, Inference.Onnx
Benchmarks → Application, Composition, Domain, Inference, Inference.Onnx, Infrastructure
Tools → Application, Domain, Infrastructure, Media
Contracts → Domain
Licensing → (nothing)
Analyzers → (nothing)
OnnxRuntime.Dnnl.Native → (nothing)
Domain → (nothing)
flowchart TD
    App[App.Avalonia] --> Sdk
    App --> Composition
    App --> Application
    App --> Domain
    App --> MediaPlayback[Media.Playback]
    App --> Licensing

    Cli[Cli] --> Sdk
    Sdk --> Composition
    Sdk --> Application
    Sdk --> Licensing

    Composition --> Application
    Composition --> Inference
    Composition --> InferenceOnnx[Inference.Onnx]
    Composition --> Infrastructure
    Composition --> Media
    Composition --> MediaPlayback
    Composition --> Licensing

    Application --> Contracts
    Application --> Domain
    Application --> Licensing

    Infrastructure --> Application
    Media --> Application
    InferenceOnnx --> Inference
    Inference --> Contracts
    Inference --> Domain
    Contracts --> Domain
    Domain --> None[nothing]
Loading

Rules of thumb

  1. Domain depends on nothing. No inference, I/O, or UI types leak into Domain.
  2. UI boundary: no inference code, no CLI parsing, no SQL in ViewModels.
  3. Contracts may reference Domain (intentional). Do not chase zero-deps without a planned refactor.
  4. Analyzers are netstandard2.0 compile-time only (ReferenceOutputAssembly=false).

In the desktop checkout, Application and related projects come from external/Trackdub/src/. Prefer upstream-friendly changes and refresh the submodule pin rather than leaving local-only diffs under external/Trackdub.

Cloud surfaces

Portal API (api.trackdub) and portal SPA (portal.trackdub) are TypeScript services for account/auth. They are not .NET layers in this graph and do not run the dubbing pipeline today.

Enforcement

dotnet test tests/Trackdub.Architecture.Tests --no-restore -m:1
# Under external/Trackdub in the app tree

When adding a project reference, update this page and the relevant AGENTS.md in the same change.

Clone this wiki locally