Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/sonar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ jobs:
/d:sonar.exclusions="**/obj/**,**/bin/**,samples/**,benchmarks/**,docs/**,tests/**"
/d:sonar.coverage.exclusions="src/**/DSoftStudio.Mediator.Generators/**"
/d:sonar.cpd.exclusions="src/**/DSoftStudio.Mediator.Generators/**"
/d:sonar.issue.ignore.multicriteria="e1,e2,e3"
/d:sonar.issue.ignore.multicriteria="e1,e2,e3,e4"
/d:sonar.issue.ignore.multicriteria.e1.ruleKey="csharpsquid:S2326"
/d:sonar.issue.ignore.multicriteria.e1.resourceKey="src/**/I*Request.cs"
/d:sonar.issue.ignore.multicriteria.e2.ruleKey="csharpsquid:S3267"
/d:sonar.issue.ignore.multicriteria.e2.resourceKey="src/**/DSoftStudio.Mediator.Generators/**"
/d:sonar.issue.ignore.multicriteria.e3.ruleKey="csharpsquid:S2743"
/d:sonar.issue.ignore.multicriteria.e3.resourceKey="src/**/DSoftStudio.Mediator/*Cache.cs"
/d:sonar.issue.ignore.multicriteria.e4.ruleKey="*"
/d:sonar.issue.ignore.multicriteria.e4.resourceKey="tests/**/*"

- name: Build
run: dotnet build DSoftStudio.Mediator.slnx -c Release --no-incremental
Expand Down
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.0] — Unreleased (pre-release `1.3.0-rc.1`)
## [1.3.0] — 2026-07-08

> Companions: `OpenTelemetry` 1.1.0-rc.1 · `HybridCache` 1.0.9-rc.1 · `FluentValidation` 1.0.9-rc.1.
> Soaking as a release candidate before promotion to the stable `1.3.0`.
> Companions: `OpenTelemetry` 1.1.0 · `HybridCache` 1.0.9 · `FluentValidation` 1.0.9.

### Added

Expand Down
5 changes: 2 additions & 3 deletions docs/mediator/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ description: "All notable changes to DSoftStudio.Mediator."

# Changelog

## [1.3.0] — Unreleased (pre-release `1.3.0-rc.1`)
## [1.3.0] — 2026-07-08

> Companions: `OpenTelemetry` 1.1.0-rc.1 · `HybridCache` 1.0.9-rc.1 · `FluentValidation` 1.0.9-rc.1.
> Soaking as a release candidate before promotion to the stable `1.3.0`.
> Companions: `OpenTelemetry` 1.1.0 · `HybridCache` 1.0.9 · `FluentValidation` 1.0.9.

### Added

Expand Down
2 changes: 1 addition & 1 deletion docs/mediator/integrations/hybridcache.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public record GetProduct(Guid Id) : IQuery<ProductDto>, ICachedRequest
}
```

That's it — the `CachingBehavior` intercepts the pipeline, checks for `ICachedRequest`, and uses `HybridCache.GetOrCreateAsync()` to cache the result. Requests that don't implement `ICachedRequest` pass through with zero overhead.
That's it — the `CachingBehavior` intercepts the pipeline, checks for `ICachedRequest`, and uses `HybridCache.GetOrCreateAsync()` to cache the result. Requests that don't implement `ICachedRequest` pass through with negligible overhead — a single `is not ICachedRequest` type-check before the behavior awaits the rest of the pipeline.

## Adding Redis as L2

Expand Down
2 changes: 1 addition & 1 deletion docs/mediator/integrations/opentelemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dotnet add package DSoftStudio.Mediator.OpenTelemetry
services
.AddMediator()
.RegisterMediatorHandlers()
.AddMediatorInstrumentation() // ← registers tracing + metrics behaviors
.AddMediatorInstrumentation() // ← registers tracing + metrics instrumentation
.PrecompilePipelines()
.PrecompileNotifications()
.PrecompileStreams();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mediator/pipeline-explorer/assets/screenshots/behaviors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mediator/pipeline-explorer/assets/screenshots/dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ A single license activates both editions, so installing one does not prevent ins
Or install from the command line:

```shell
code --install-extension DSoftStudio.dsoftstudio-mediator
code --install-extension DSoftStudio.mediator-pipeline-explorer
```

### Install from a `.vsix` file

If your environment can't reach the Marketplace, download the latest release from the [GitHub releases page](https://github.com/DSoftStudio/Mediator.Enterprise/releases) and install:

```shell
code --install-extension dsoftstudio-mediator-<version>.vsix
code --install-extension mediator-pipeline-explorer-<target>-<version>.vsix
```

### First launch
Expand Down Expand Up @@ -135,7 +135,7 @@ Your license persists across IDE restarts. See [Troubleshooting: activation fail
### Visual Studio Code

```shell
code --uninstall-extension DSoftStudio.dsoftstudio-mediator
code --uninstall-extension DSoftStudio.mediator-pipeline-explorer
```

Or remove it from the Extensions view.
Expand Down
32 changes: 16 additions & 16 deletions docs/mediator/pipeline-explorer/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ description: "Your first solution scan, profiling session, and source navigation

By the end of this guide you will have scanned your first solution, navigated to a handler in one click, and watched live profiling data flow in.

This walkthrough assumes you have already [installed the extension](installation.md) and opened a solution that references `DSoftStudio.Mediator`. The steps are identical in Visual Studio Code and Visual Studio; the screenshots below are drawn from boththe layout and workflow match in either IDE.
This walkthrough assumes you have already [installed the extension](installation.md) and opened a solution that references `DSoftStudio.Mediator`. The core workflow is the same in Visual Studio Code and Visual Studio, and the screenshots below are drawn from both. A few features are Visual Studio-only, however — detaching/docking the graph, the section-filter dropdown, and some context-menu commands — and those differences are called out inline as you reach them.

---

Expand Down Expand Up @@ -48,7 +48,7 @@ The tree populates with three sections — **Request Pipelines**, **Notification
The badge after each request pipeline tells you two things at a glance:

- **CQRS kind** — `Command`, `Query`, or `Request` (when neither marker interface is implemented).
- **Pipeline mode** — `PassThrough` (handler only), `BehaviorsOnly`, or `Full` (pre/post-processors + behaviors).
- **Pipeline mode** — **Direct** (handler only), **Behaviors**, or **Full Pipeline** (pre/post-processors + behaviors).

If the tree is empty, click **Refresh** in the toolbar. If it is still empty after refresh, see [Troubleshooting: empty tree](../troubleshooting/empty-tree.md).

Expand All @@ -72,27 +72,27 @@ Click any item — handler, behavior, or call site — and the IDE jumps to the

The execution-order table numbers every step in the exact order it runs — pre-processors, behaviors, the handler, then post-processors. Behavior and processor times are **inclusive**: each wraps the steps below it, so its average equals the combined time of everything it surrounds plus its own overhead.

> **Tip:** right-click any node for **Go to Definition**, **Find All References**, **Copy Type Name**, and **Pin to Quick Access**.
> **Tip:** right-click any node for a context menu. In **Visual Studio** it offers **Go to Definition**, **Find All References**, **Copy Type Name**, and **Pin to Quick Access**. In **VS Code** it offers **Go to Source**, **Show Pipeline Graph**, and **Copy Type Name** (no Find All References / Pin to Quick Access).

---

## 3. Visualize the pipeline graph

The detail panel exposes a **graph** toggle (the branching icon in the toolbar) that opens the interactive graph below the detail.
The detail panel exposes a **graph** toggle (the branching icon in the toolbar) that opens the interactive graph.

- **Pan** — drag empty space.
- **Zoom** — mouse wheel.
- **Click a node** — navigates to source in the editor.
- **Detach** — pop the graph out into its own resizable window, then **Dock back** when you're done.
- **Detach / Dock** (Visual Studio only) — pop the graph out into its own resizable window, then **Dock back** when you're done.

The graph lays out the full request flow left to right: **Send → request → pre-processors → behaviors → handler → post-processors**. It sits docked beneath the detail panel, so you can read the structure and the step list together.
The graph lays out the full request flow left to right: **Send → request → pre-processors → behaviors → handler → post-processors**. In **Visual Studio** it sits docked beneath the detail panel, so you can read the structure and the step list together; in **VS Code** it opens as a side-by-side editor tab next to the detail.

<figure class="screenshot">
<img src="../assets/screenshots/graph-view.png" alt="Detail panel above a docked pipeline graph for PlaceOrderCommand: Send, the command, two pre-processors, the handler, and a post-processor laid out left to right">
<figcaption>The graph docked beneath the detail panel for a <code>Full</code> pipeline — <code>Send → PlaceOrderCommand → LoggingPreProcessor → ValidationPreProcessor → PlaceOrderCommandHandler → AuditPostProcessor</code> — every node click-to-source.</figcaption>
</figure>

Need more room? **Detach** the graph into its own window — handy for wide pipelines or walking your team through the flow — then **Dock back** when you're done.
Need more room? In **Visual Studio** you can **Detach** the graph into its own window — handy for wide pipelines or walking your team through the flow — then **Dock back** when you're done. (In **VS Code** the graph already opens as a full side-by-side editor tab, so there is no detach/dock step.)

<figure class="screenshot">
<img src="../assets/screenshots/graph-view-detached.png" alt="The pipeline graph popped out into its own full-window detached view, showing the end-to-end flow from Send through the processors to the post-processor">
Expand All @@ -117,7 +117,7 @@ A handler rarely works alone — it often publishes a notification or dispatches

## 4. Start runtime profiling

Profiling captures live timings as your code runs. The profiling hooks are wired into your application **automatically** by the analyzer — there is nothing to add to `Program.cs`. As long as the project that calls `services.AddMediator(...)` has the Pipeline Explorer analyzer loaded (which the extension auto-injects via `Directory.Build.props`), the hooks are emitted at compile time with zero allocation overhead until a profiling session is attached.
Profiling captures live timings as your code runs. The profiling hooks are wired into your application **automatically** by the analyzer — there is nothing to add to `Program.cs`, and nothing is written into your repository. The extension injects the analyzer machine-locally through an MSBuild user-extensions file (`$(MSBuildUserExtensionsPath)\DSoftStudio.Mediator\enabled.props`), so every build on your machine picks it up without touching your solution's `Directory.Build.props`. (Older versions used to write a marked block into the repo's `Directory.Build.props`; those legacy markers are now actively stripped.) As long as the project that calls `services.AddMediator(...)` has the analyzer loaded, the hooks are emitted at compile time with zero allocation overhead until a profiling session is attached.

### Attach the profiler

Expand All @@ -131,18 +131,18 @@ Profiling captures live timings as your code runs. The profiling hooks are wired

Then issue requests against your application — run an integration test, exercise an endpoint, replay traffic. Within a second or two, the **Runtime Profiler** fills with live timings.

Each behavior is timed independently. Select a pipeline's **Behaviors** node to see every behavior's own runtime profile side by side — calls, average, self time, p50/p95/p99, and max — so you can tell which cross-cutting concern (validation, logging, transactions) is costing you. Tail-heavy handlers — those with a p99 far above the median — are flagged so you can spot bottlenecks instantly. The default threshold (`tailHeavyMinP99Ms`) prevents false positives on sub-millisecond noise.
Each component is timed independently. Select a pipeline's **Components** node to see every component's own runtime profile side by side — calls, average, self time, p50/p95/p99, and max — so you can tell which cross-cutting concern (validation, logging, transactions) is costing you. Tail-heavy handlers — those with a p99 far above the median — are flagged so you can spot bottlenecks instantly. The default threshold (`tailHeavyMinP99Ms`) prevents false positives on sub-millisecond noise.

<figure class="screenshot">
<img src="../assets/screenshots/behaviors.png" alt="Behaviors panel listing each pipeline behavior with its calls, average, self time, p50/p95/p99, max, and kind (Pre or Post)">
<figcaption>The <strong>Behaviors</strong> panel — each behavior's runtime profile side by side (calls, avg, self, p50/p95/p99, max) with its kind (<code>Pre</code> / <code>Post</code>), so the costly cross-cutting concern stands out.</figcaption>
<img src="../assets/screenshots/behaviors.png" alt="Components panel listing each pipeline component with its calls, average, self time, p50/p95/p99, max, and kind (Pre or Post)">
<figcaption>The <strong>Components</strong> panel — each component's runtime profile side by side (calls, avg, self, p50/p95/p99, max) with its kind (<code>Pre</code> / <code>Post</code>), so the costly cross-cutting concern stands out.</figcaption>
</figure>

Select a single behavior to see its type, lifetime, and source file — with one click to jump to where it's defined.
Select a single component to see its type, lifetime, and source file — with one click to jump to where it's defined.

<figure class="screenshot">
<img src="../assets/screenshots/behavior-detail.png" alt="Detail for a single behavior: its runtime-stats row plus a properties panel with type, kind, lifetime, file path, and Open in Editor / Copy buttons">
<figcaption>Drilling into one behavior — its runtime stats plus type, kind, lifetime, and source file, with <strong>Open in Editor</strong> to jump straight to its definition.</figcaption>
<img src="../assets/screenshots/behavior-detail.png" alt="Detail for a single component: its runtime-stats row plus a properties panel with type, kind, lifetime, file path, and Open in Editor / Copy buttons">
<figcaption>Drilling into one component — its runtime stats plus type, kind, lifetime, and source file, with <strong>Open in Editor</strong> to jump straight to its definition.</figcaption>
</figure>

<figure class="screenshot">
Expand All @@ -161,15 +161,15 @@ Sort the table by **p99** or **Avg** to identify the worst offender. The **Hot P

Click the bottleneck row to jump to the source. Fix it, re-run, and watch the new numbers replace the old.

When you're done, click **Stop** to detach the profiler. Click **Clear** to reset the in-memory buffer, or **Snapshot** to capture the current state for later comparison.
When you're done, click **Stop** to detach the profiler. Click **Clear** to reset the in-memory buffer.

---

## 5. Filter and search

As your codebase grows, the tree grows with it. Two tools keep it manageable:

- **Section filter** — the dropdown at the top of the toolbar narrows the tree to one of **All / Commands / Queries / Notifications / Streams**. Picking *Commands* leaves only `ICommand<>`-derived pipelines visible; *Queries* leaves only `IQuery<>`-derived ones.
- **Section filter** (Visual Studio only) — the dropdown at the top of the toolbar narrows the tree to one of **All / Commands / Queries / Notifications / Streams**. Picking *Commands* leaves only `ICommand<>`-derived pipelines visible; *Queries* leaves only `IQuery<>`-derived ones. **VS Code** has no section-filter dropdown — narrow the tree with the search box below instead.
- **Search box** — type any fragment of a type name, handler name, behavior name, or file path. Matches highlight and the tree collapses to the matching pipelines.

`Ctrl+F` (VS Code) or click the search box (VS) focuses the input. `Esc` clears it.
Expand Down
7 changes: 4 additions & 3 deletions docs/mediator/pipeline-explorer/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Pipeline Explorer is a commercial IDE extension that scans your solution, discov

<figure class="screenshot">
<img src="assets/screenshots/dashboard.png" alt="Pipeline Explorer with the discovered pipeline tree on the left and the Dashboard on the right showing handler counts, pipeline-mode and lifetime distributions, and recent activity">
<figcaption>Pipeline Explorer — the discovered pipeline tree on the left, the Dashboard on the right: live counts of handlers, behaviors, notifications, and streams, the pipeline-mode and DI-lifetime distributions, and a recent-activity feed.</figcaption>
<figcaption>Pipeline Explorer — the discovered pipeline tree on the left, the Dashboard on the right: live counts of handlers, components, notifications, and streams, the pipeline-mode and DI-lifetime distributions, and a recent-activity feed.</figcaption>
</figure>

---
Expand All @@ -46,7 +46,7 @@ Pipeline Explorer answers all of these in seconds, with one click to source.

| Capability | Outcome |
|---|---|
| **Pipeline tree explorer** | Browse Commands, Queries, Notifications, and Streams grouped by kind, with at-a-glance badges and live counts. |
| **Pipeline tree explorer** | Browse request pipelines (commands & queries), notifications, and streams, with at-a-glance badges and live counts. |
| **Click-to-source navigation** | Click any node — handler, behavior, call site — and the IDE opens the file at the right line. |
| **Interactive pipeline graph** | See pre-processors → behaviors → handler → post-processors visualized per pipeline, with notification fan-out and nested calls inline. Detach it into its own window, and overlay per-node timing + health badges once profiling is on. |
| **Runtime profiler** | Live handler / behavior timings with p50 / p95 / p99 percentiles, error rates, and tail-heavy detection — plus per-pipeline statistics, request telemetry, and a Hot Path / Flame breakdown of where each request spends its time. |
Expand Down Expand Up @@ -97,7 +97,8 @@ See the [full troubleshooting hub](troubleshooting/index.md) for the diagnostic

Pipeline Explorer ships as two editions that share the same backend, the same data model, and the same workflow:

- **Visual Studio Code extension** — available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=DSoftStudio.dsoftstudio-mediator). Bundled server auto-spawns on Windows, macOS, and Linux.
<!-- TODO(doc-review): confirm the extension is actually published under this Marketplace slug before release -->
- **Visual Studio Code extension** — available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=DSoftStudio.mediator-pipeline-explorer). Bundled server auto-spawns on Windows, macOS, and Linux.
- **Visual Studio extension** — available on the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=DSoftStudio.MediatorPipelineExplorer). Visual Studio 2022 17.0+ and 2026.

A single license activates both editions.
Expand Down
Loading
Loading