CodeGraphToDgml
Code Graph to DGML is a Visual Studio extension that builds DGML graphs from the symbol at the editor caret.

Building and maintaining this took real ideation, time, design effort, and compute (including LLM usage) to get right. If it's useful to you, consider sponsoring its development — any amount helps keep it going. 💛
Features
Traverse Up to DGML
- traverses callers upward from C# and Visual Basic methods, properties, and events
- limits traversal by maximum depth and node count
- filters properties, events, external symbols, and generated code
- discovers forms, pages, and windows that host UI components (WinForms, WebForms, WPF, Blazor, MAUI, Avalonia) and adds them with UsedBy links
- follows nested component hosting up to a configurable depth
Traverse Down to DGML
- traverses callees downward from C# and Visual Basic methods, properties, and events (VB call sites include parenless calls,
Call, RaiseEvent, AddHandler/RemoveHandler, AddressOf, With blocks, and From/With initializers)
- follows interface implementations (
Implements links) and virtual/abstract overrides in derived types (Overrides links) so the graph reflects the methods that may actually run at each call site
- limits traversal by maximum depth and node count
- filters properties, events, external symbols, and generated code
All References to DGML
- mirrors Visual Studio's built-in
Find All References (Shift+F12) for the symbol at the caret
- supports C# and Visual Basic types (class, struct, interface, record) and members (methods, properties, events, fields)
- adds a
References link from each enclosing referrer (method, property, event, field, or type) to the target symbol
- limits the result by maximum node count and respects the external symbol and generated code filters (references are a single level, so maximum depth does not apply)
Traverse Down to Sequence Diagram (with Control Flow)
- same traversal as the command above, rendered with Mermaid combined fragments so the diagram shows when each call happens
if / else if / else, switch statements and expressions, and ?: become alt sections (an if whose other branches make no calls becomes opt)
for, foreach, while, and do become loop; catch clauses become break; try bodies, finally, using, lock, lambdas, and ?. are transparent
- a call inside a condition (
if (Check())) is placed before the fragment, since it runs before the branch is chosen
- an interface member or virtual method with several implementations renders as one
alt with a branch per implementing type
- the same callee reached from two branches appears once per branch; a fragment cut by the diagram splitter is re-opened in the next part with a
(cont.) marker
- fragment labels are truncated to
Max condition label length (default 40)
- Visual Basic:
If/ElseIf/Else, single-line If, Select Case, If(a, b, c), For/For Each/While/Do loops, and Catch blocks map the same way
- output files are named
CodeSequenceFlow-{timestamp}.md / .html
Common
- appends to or replaces an open DGML document
- creates a new DGML document under
{SolutionDir}\.vs\CodeGraphToDgml\ when no target document is open (falls back to %TEMP% without a solution)
- reports progress in the status bar and a cancellable modal dialog
- writes execution details to a dedicated Output window pane
Prerequisites
The DGML editor is included by default in Visual Studio Enterprise. For Community or Professional editions it must be installed separately:
- Open Visual Studio Installer.
- Click Modify on your Visual Studio installation.
- Switch to the Individual components tab.
- Search for DGML editor.
- Check the component and click Modify to install it.
Without the DGML editor, Visual Studio cannot open or display .dgml files generated by this extension.
Solution Layout
src/CodeGraphToDgml.Core: dependency-free graph model, DGML serializer, and Mermaid sequence serializer
src/CodeGraphToDgml.Roslyn: host-free Roslyn call-site detection, filters, and dispatch resolution (testable without Visual Studio)
src/CodeGraphToDgml.Vsix: Visual Studio host integration, commands, options, and the traversal providers
tests/CodeGraphToDgml.Tests: MSTest unit tests for the Core and Roslyn projects
Build
Build the extension from the Release configuration to produce the VSIX package:
dotnet build .\CodeGraphToDgml.sln -c Release
The repository includes both CodeGraphToDgml.sln and CodeGraphToDgml.slnx.
The generated VSIX is written to src\CodeGraphToDgml.Vsix\bin\Release\net48\CodeGraphToDgml.Vsix.vsix.
All projects are SDK-style, including the VSIX project (VSSDKBuildToolsAutoSetup), and package versions are managed centrally in Directory.Packages.props.
Versioning
The extension version lives in one place: <Version> in Directory.Build.props. The VSIX manifest resolves it at build time through the |%CurrentProject%;GetVsixVersion| placeholder, and Vsix.Version is generated into obj\Vsix.Version.g.cs. To release, bump that single value and tag the commit.
Release
The Build workflow runs on every push and pull request (build, tests, VSIX artifact, and a check that the packaged manifest version equals Directory.Build.props). Pushing a tag vX.Y.Z additionally:
- verifies the tag matches
Directory.Build.props,
- creates a GitHub release with the VSIX attached, and
- waits for approval on the
marketplace environment, then publishes the VSIX to the Visual Studio Marketplace with VsixPublisher.exe using publishManifest.json.
One-time setup on GitHub:
- Create the
marketplace environment (Settings > Environments) and add yourself as a required reviewer so publishing needs an explicit approval.
- Add the secret
VS_MARKETPLACE_PAT (Settings > Secrets and variables > Actions). Its value is an Azure DevOps personal access token: sign in at https://dev.azure.com, open User settings > Personal access tokens > New token, choose Organization "All accessible organizations", Scopes "Custom defined" with Marketplace: Publish (or Manage), and copy the token. The account must be a member of the guerchele publisher at https://marketplace.visualstudio.com/manage.
Manual Test Matrix
| Area |
Scenario |
Expected Result |
| Command visibility |
Open a .cs or .vb file and right-click in the editor |
Traverse Up to DGML is visible and enabled |
| Command filtering |
Open a non-C# and non-VB file and right-click in the editor |
Command is hidden or disabled |
| Supported symbols |
Place caret on a method, property, and event in separate checks |
Traversal starts successfully for each supported symbol kind |
| Unsupported caret target |
Place caret on whitespace, namespace, class name, or local variable |
Informational message is shown and no traversal runs |
| Depth limit |
Set Maximum depth to 1 and run traversal on a symbol with multiple caller levels |
Only direct callers are included |
| Node limit |
Set Maximum node count to 1 or 2 and run traversal |
Traversal stops when the node cap is reached |
| Symbol inclusion |
Toggle Include properties, Include events, Include external symbols, and Include generated code |
Result graph respects each option |
| DGML append mode |
Open an existing DGML file, choose append mode, run the command twice |
Existing graph content is preserved and duplicate nodes/links are not added |
| DGML replace mode |
Open an existing DGML file, choose replace mode, run the command |
Existing node/link content is replaced by the new traversal result |
| Target selection |
With one or more DGML docs open, test AlwaysAsk, AlwaysCreateNewTemporary, and ReuseActiveIfOpen |
Target document behavior matches the selected option |
| New document creation |
Run the command when no DGML document is open |
A CodeGraph-{timestamp}.dgml document is created under {SolutionDir}\.vs\CodeGraphToDgml\ |
| Window activation |
Toggle Activate result document and rerun |
DGML document is activated only when the option is enabled |
| Progress and cancel |
Start a traversal large enough to observe progress, then cancel |
Status bar updates are shown and cancellation stops the operation cleanly |
| Output logging |
Run traversal with Show detailed output enabled |
Output pane shows resolved symbol, counts, target document, and errors when applicable |
| Packaging |
Build Release and inspect the output folder |
A VSIX is produced and can be installed into a VS 2022 Experimental Instance |
| Traverse Down to DGML |
|
|
| Command visibility |
Open a .cs or .vb file and right-click in the editor |
Traverse Down to DGML is visible and enabled |
| Supported symbols |
Place caret on a method, property, and event in separate checks |
Traversal starts successfully for each supported symbol kind |
| Direct callees |
Run on a method that calls several other methods |
Graph includes the called methods with Calls links from the starting method |
| Interface dispatch |
Run on a method that invokes an interface member with multiple implementations |
Graph includes each implementing member reachable from the call site |
| Virtual overrides |
Run on a method that calls a virtual or abstract member |
Graph includes each overriding member in derived types, linked from the base member with a green dashed Overrides link |
| Depth limit |
Set Maximum depth to 1 and run on a method with multi-level callees |
Only direct callees are included |
| Node limit |
Set Maximum node count to 1 or 2 and run traversal |
Traversal stops when the node cap is reached |
| All References to DGML |
|
|
| Command visibility |
Open a .cs or .vb file and right-click on a class, struct, interface, record, method, property, event, or field |
All References to DGML is visible and enabled |
| Unsupported caret target |
Place caret on whitespace, a namespace, a using/Imports directive, or a local variable |
Informational message is shown and no traversal runs |
| Type references |
Run on a type used in several other files |
Graph includes each enclosing referrer (method/property/type) with a References link to the target type |
| Member references |
Run on a method, property, event, or field used from multiple call sites |
Graph includes each enclosing referrer with a References link to the target member |
| Node limit |
Set Maximum node count to a small value and run on a widely used symbol |
Traversal stops when the node cap is reached (Maximum depth does not apply; references are a single level) |
| Filter respect |
Toggle Include external symbols and Include generated code |
Result graph respects each option |
| Traverse Down to Sequence Diagram (with Control Flow) |
|
|
| Branches |
Run on a method with if/else, switch, and ?: |
Calls appear inside alt sections labelled with the condition; a lone branch renders as opt |
| Loops and catch |
Run on a method with foreach/for/while/do and try/catch |
Calls inside loops are wrapped in loop, calls in catch in break; calls in the try body are not wrapped |
| Dispatch |
Run on a method calling an interface with two implementations |
One alt with a branch per implementing type |
| Splitting |
Lower Max messages per diagram so a fragment is cut across parts |
The next part re-opens the fragment with a (cont.) label and every part is balanced |
| Component Hosts |
|
|
| Host discovery |
Place caret on a method inside a WinForms/WPF UserControl that is used on a Form, run "Traverse Up to DGML" |
Form appears with an orange UsedBy link to the UserControl |
| Nested hosting |
UserControl A hosted in UserControl B hosted in a Form, set Maximum host depth to 2+ |
All three levels appear with UsedBy chains: Form → B → A |
| Host depth limit |
Same nested setup, set Maximum host depth to 1 |
Only direct host (B → A) appears, Form is not discovered |
| Opt-out |
Disable Include component hosts, rerun on a method inside a UserControl |
No host nodes or UsedBy links appear |
| |