Table of Contents

Architecture Overview

DBTools is a modular Revit add-in suite built with modern C#/.NET practices. It provides a collection of productivity tools for structural engineers working in Autodesk Revit.

High-Level Architecture

graph TB
    subgraph Revit["Revit Host"]
        RevitAPI["Revit API<br/>(RevitAPI.dll, RevitAPIUI.dll)"]
    end
    
    subgraph DBTools["DBTools Add-in"]
        Loader["DBTools.Loader<br/>(Entry Point)"]
        App["DBTools.App<br/>(DBTools.dll)"]
        Core["DBTools.Core<br/>(Core Library)"]
        Themes["DBTools.Themes<br/>(WPF Resources)"]
        
        subgraph Tools["Tool Modules (File-linked)"]
            GM["GM"]
            SGT["SGT"]
            TDV["TDV"]
            Others["..."]
        end
    end
    
    Revit -->|".addin manifest"| Loader
    Loader -->|"Loads & resolves"| App
    App --> Core
    App --> Themes
    App -->|"Discovers via manifest.yml"| Tools
    Core --> RevitAPI
    
    style Revit fill:#f5f5f5,stroke:#333
    style DBTools fill:#e3f2fd,stroke:#1946B9
    style Tools fill:#fff3e0,stroke:#FEC425

ASCII Diagram (for reference)

+-----------------------------------------------------------------------------------+
|                                 Revit Host                                        |
+-----------------------------------------------------------------------------------+
        |                                                           |
        v                                                           v
+-------------------+                                    +----------------------+
|  DBTools.Loader   |  <-- Revit .addin manifest         |   Revit API          |
|  (Entry Point)    |      points here                   |   (RevitAPI.dll,     |
+-------------------+                                    |   RevitAPIUI.dll)    |
        |                                                +----------------------+
        | Loads DBTools.dll, installs                              ^
        | EmbeddedAssemblyResolver                                 |
        v                                                          |
+-------------------+     References      +----------------------+ |
|   DBTools.App     | -----------------> |    DBTools.Core      |-+
|   (DBTools.dll)   |                    |    (Core Library)    |
|                   |                    +----------------------+
|  - AddinEntry     |                              ^
|  - Tool Modules   |                              |
|  - Ribbon UI      |     References               |
|  - Commands       | -----------------> +----------------------+
+-------------------+                    |   DBTools.Themes     |
        |                                |   (WPF Resources)    |
        | Discovers via manifest.yml     +----------------------+
        v
+-------------------+
|   Tool Modules    |
|  (File-linked)    |
|  - GM, SGT, TDV   |
|  - Settings       |
|  - Structural/*   |
+-------------------+

Source: src/DBTools.Loader/Addin/AddinEntry.cs:17-47

Project Organization

The solution follows a layered architecture with clear separation of concerns:

Core Projects

Project Purpose Target Frameworks
DBTools.Loader Revit entry point; loads DBTools.dll and resolves embedded assemblies net48, net8.0-windows
DBTools.App Main application assembly (outputs as DBTools.dll); contains ribbon UI and tool registration net48, net8.0-windows
DBTools.Core Core library with shared infrastructure (DI, logging, settings, Revit abstractions) net48, net8.0-windows
DBTools.Themes WPF theme resources and styling (HandyControl) net48, net8.0-windows
DBTools.Sandbox Standalone WPF app for UI development without Revit net48, net8.0-windows

Source: src/ directory structure

Tool Projects (File-Linked into DBTools.App)

Tools are organized under src/Tools/ and compiled into the main DBTools.dll assembly via MSBuild file linking:

Tools/
+-- Common/
|   +-- GM/               # Global Mapper
|   +-- TDV/              # Type Data Viewer
|   +-- ElevationTags/
|   +-- 3DElementsFromList/
+-- Structural/
|   +-- SGT/              # Structural Grid Tool
|   +-- FoundationTags/
|   +-- FramingJoins/
|   +-- JoistGirderWeight/
|   +-- OrganizeFoundationTypes/
|   +-- AnalyticalSnapToLevel/
+-- Settings/             # Settings management tool
+-- Testing/
    +-- ERFT/             # Elevation Reference Framing Tool
    +-- RecordSet/        # RecordSet file management
    +-- VTC/              # View Test Coordinator

Source: src/DBTools.App/DBTools.App.csproj:61-78 (file linking configuration)

Tool source files are linked (not copied) into the DBTools.App project:

<Compile Include="..\Tools\**\*.cs"
         Exclude="..\Tools\**\Tests\**\*.cs;..\Tools\**\obj\**\*.cs"
         Link="Tools\%(RecursiveDir)%(Filename)%(Extension)" />

Source: src/DBTools.App/DBTools.App.csproj:64-66

Multi-Year Revit Support

DBTools supports multiple Revit versions through dual target frameworks:

Revit Version Target Framework Runtime
Revit 2024 net48 .NET Framework 4.8
Revit 2025+ net8.0-windows .NET 8

Source: build/Revit.props:2-6

The build system auto-detects installed Revit versions and builds for all available years:

<DBT_RevitLegacyTFM>net48</DBT_RevitLegacyTFM>
<DBT_RevitModernTFM>net8.0-windows</DBT_RevitModernTFM>
<DBT_RevitTargetFrameworks>$(DBT_RevitLegacyTFM);$(DBT_RevitModernTFM)</DBT_RevitTargetFrameworks>

Source: build/Revit.props:3-5

Tool Discovery and Registration

DBTools uses a YAML manifest-driven tool discovery system. Each tool declares its module, commands, and UI configuration in a manifest.yml file.

Manifest Structure

id: DBTools.GM
assembly: DBTools
moduleType: DBTools.GM.GmToolModule
order: 0
sandboxWindows:
  - id: DBTools.GM.Main
    displayName: "Global Mapper"
    group: "Common"
    windowType: "DBTools.GM.Shell.UI.Views.GmWindow"
    designTimeViewModelType: "DBTools.GM.Shell.DesignTime.GmShellDesignTimeViewModel"
tool:
  ribbonTools:
    - internalName: DBTools.GM
      commandType: DBTools.GM.Features.GmCommand
      availabilityType: DBTools.App.Tools.Availability.DbtDocumentAvailability
      runProfile: InlineUi
      displayText: "Global Mapper"
      iconBaseKey: gm
      controlKind: PushButton

Source: src/Tools/Common/GM/manifest.yml:1-27

Discovery Flow

sequenceDiagram
    participant App as DBTools.App
    participant Loader as DbtToolManifestLoader
    participant Catalog as DbtToolModuleCatalog
    participant Module as DbtToolModule
    participant DI as IServiceCollection
    participant Ribbon as RibbonManager

    App->>Loader: ScanEmbeddedResources()
    Loader-->>App: List<DbtToolManifest>
    
    loop For each manifest
        App->>Catalog: CreateModule(manifest)
        Catalog->>Module: new() via reflection
        Module-->>Catalog: DbtToolModule instance
        
        App->>Module: RegisterSettings()
        App->>Module: RegisterServices()
        Module->>DI: AddScoped<T>()
        
        App->>Module: RegisterHooks()
        App->>Ribbon: RegisterRibbonToolsFromManifest()
    end
  1. Manifest Loading: DbtToolManifestLoader scans embedded resources for manifest.yml files
  2. Module Instantiation: DbtToolModuleCatalog creates DbtToolModule instances via reflection
  3. Service Registration: Each module's RegisterServices(), RegisterSettings(), and RegisterHooks() are called
  4. Ribbon Tool Registration: RegisterRibbonToolsFromManifest() parses ribbon definitions and registers commands

Source: src/DBTools.Core/Tools/DbtToolModuleCatalog.cs:11-64

Tool Module Base Class

All tools inherit from DbtToolModule, which provides hooks for:

  • RegisterSettings() - Bind configuration sections to strongly-typed options
  • RegisterServices() - Register tool-specific DI services
  • RegisterSettingsPacks() - Register settings UI definitions
  • RegisterHooks() - Register event handlers (e.g., DocumentOpened, ViewActivated)

Source: src/DBTools.Core/Tools/DbtToolModule.cs:9-49

Dependency Injection Architecture

DBTools uses Microsoft.Extensions.DependencyInjection with a two-tier service scope pattern:

Singleton Services (Application Lifetime)

  • IDbtLoggingHost - Serilog-based logging infrastructure
  • IConfiguration - Settings from settings.{YEAR}.json
  • DbtToolRegistry - Discovered tool registrations
  • ISafeExecutor - Centralized error handling
  • ISettingsProvider - Settings read/write access

Scoped Services (Per-Command Lifetime)

  • IRevitRunScope - Active command execution context
  • IRevitCallGate - Thread-safe Revit API access
  • ITransactionRunner - Transaction management
  • ITransactionGroupService - Transaction grouping

Source: src/DBTools.App/Bootstrap/DbtServiceBootstrapper.cs:68-130

Assembly Loading Strategy

Loader Bootstrap

The DBTools.Loader assembly is the Revit entry point. It:

  1. Locates DBTools.dll in the same directory
  2. Installs EmbeddedAssemblyResolver for runtime dependency resolution
  3. Pre-loads critical assemblies (Configuration, Serilog) on net48
  4. Reflectively creates and invokes DBTools.App.AddinEntry

Source: src/DBTools.Loader/Addin/AddinEntry.cs:17-47

Embedded Dependencies

Dependencies are embedded as resources in DBTools.dll to minimize deployment complexity:

<EmbeddedResource Include="%(_EmbedLogicalDistinct.SourcePath)"
                  LogicalName="%(_EmbedLogicalDistinct.Identity)" />

Source: src/DBTools.App/DBTools.App.csproj:265-266

The resolver uses different strategies per framework:

Framework Strategy
net48 ILRepack merges most assemblies; ricaun.* embedded as resources
net8.0 All dependencies embedded as resources, loaded via AssemblyLoadContext

Source: src/DBTools.Loader/AssemblyResolution/EmbeddedAssemblyResolver.cs:14-96

WPF Theme Assemblies

WPF resource assemblies that use pack:// URIs must be loaded from files because URI resolution requires Assembly.Location. In DBTools, this includes DBTools.HandyControl (vendored) and DBTools.Themes.

Source: src/DBTools.Loader/AssemblyResolution/EmbeddedAssemblyResolver.cs:260-288

Build System Overview

The build uses NUKE (C# build automation) invoked via build.sh:

# Fast incremental build (default)
bash build.sh

# Clean rebuild
bash build.sh --clean

# Build specific Revit year
bash build.sh -y 2025 BuildAll

# Common targets
bash build.sh BuildAll          # Build everything
bash build.sh BuildApp          # Build DBTools.dll only
bash build.sh BuildSandbox      # Build UI sandbox
bash build.sh PromoteToDist     # Stage for deployment

Source: build.sh:33-71

Key build features:

  • Centralized Artifacts: All outputs go to .artifacts/ (not per-project bin/obj)
  • Vendored Dependencies: UI assemblies built via build-vendored-deps.sh
  • Strict Analysis: TreatWarningsAsErrors=true, Roslyn analyzers enabled
  • Multi-Year: Builds for all detected Revit installations

Source: Directory.Build.props:7-28 (centralized artifacts), Directory.Build.props:142-151 (strict analysis)

For detailed build pipeline documentation, see Build Pipeline.

Error Handling Philosophy

All entrypoints execute within ISafeExecutor, which:

  • Catches and logs all exceptions
  • Displays user-friendly error dialogs
  • Prevents silent failures
  • Centralizes error reporting

Source: src/DBTools.App/Bootstrap/DbtServiceBootstrapper.cs:435-436

Non-Negotiable Rules:

  • No fallbacks that hide failures
  • No silent exception swallowing
  • No returning defaults as if nothing failed

Verification Status

Check Status
Source anchors for all claims Yes
UNVERIFIED markers where needed No (all verified)
Cross-references added Yes
Examples tested N/A
No assumptions without evidence Yes

Verified by: docs-run-20260124-020412
Date: 2026-01-24