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
- Manifest Loading:
DbtToolManifestLoaderscans embedded resources formanifest.ymlfiles - Module Instantiation:
DbtToolModuleCatalogcreatesDbtToolModuleinstances via reflection - Service Registration: Each module's
RegisterServices(),RegisterSettings(), andRegisterHooks()are called - 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 optionsRegisterServices()- Register tool-specific DI servicesRegisterSettingsPacks()- Register settings UI definitionsRegisterHooks()- 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 infrastructureIConfiguration- Settings fromsettings.{YEAR}.jsonDbtToolRegistry- Discovered tool registrationsISafeExecutor- Centralized error handlingISettingsProvider- Settings read/write access
Scoped Services (Per-Command Lifetime)
IRevitRunScope- Active command execution contextIRevitCallGate- Thread-safe Revit API accessITransactionRunner- Transaction managementITransactionGroupService- 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:
- Locates
DBTools.dllin the same directory - Installs
EmbeddedAssemblyResolverfor runtime dependency resolution - Pre-loads critical assemblies (Configuration, Serilog) on net48
- 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-projectbin/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
Related Documentation
- Build Pipeline - Detailed build system reference
- Test Pipeline - Testing infrastructure
- Project References - Dependency relationships
- DBTools.Core - Core library documentation
- DBTools.Loader - Revit entry point
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