You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -111,6 +111,8 @@ public class LoggingMiddleware
111
111
}
112
112
```
113
113
114
+
**Cross-Assembly Limitation**: Middleware must be defined in the same project as handlers. The source generator only has access to the current project's source code. Use linked files (`<Compile Include="..." Link="..." />` in `.csproj`) to share middleware across projects, and declare middleware classes as `internal` to avoid type conflicts.
115
+
114
116
### Execution Semantics
115
117
116
118
-**Invoke/InvokeAsync**: Requires EXACTLY one handler. Throws if zero or multiple handlers found.
Copy file name to clipboardExpand all lines: docs/guide/middleware.md
+122Lines changed: 122 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -363,6 +363,128 @@ public class PartialMiddleware
363
363
}
364
364
```
365
365
366
+
## Cross-Assembly Middleware Limitation
367
+
368
+
### Understanding the Limitation
369
+
370
+
Middleware must be defined in the **same project** as your message handlers. This is because middleware is discovered and woven into handler wrappers at compile-time by the source generator, which only has access to the current project's source code.
371
+
372
+
**This will NOT work:**
373
+
374
+
```text
375
+
Solution/
376
+
├── Common.Middleware/ # Project A
377
+
│ └── LoggingMiddleware.cs # ❌ Won't be discovered
378
+
└── Orders.Handlers/ # Project B (references A)
379
+
└── OrderHandler.cs # Handler generated without logging
380
+
```
381
+
382
+
The source generator in `Orders.Handlers` cannot see the `LoggingMiddleware` source code from the referenced `Common.Middleware` project.
383
+
384
+
### Recommended Solution: Linked Files
385
+
386
+
The recommended approach is to use **linked files** to share middleware source code across multiple projects:
387
+
388
+
**Project Structure:**
389
+
390
+
```text
391
+
Solution/
392
+
├── Common.Middleware/
393
+
│ └── Middleware/
394
+
│ ├── LoggingMiddleware.cs
395
+
│ ├── ValidationMiddleware.cs
396
+
│ └── AuthorizationMiddleware.cs
397
+
├── Orders.Handlers/
398
+
│ ├── OrderHandler.cs
399
+
│ └── Middleware/ # Linked files from Common.Middleware
400
+
│ ├── LoggingMiddleware.cs (link)
401
+
│ ├── ValidationMiddleware.cs (link)
402
+
│ └── AuthorizationMiddleware.cs (link)
403
+
└── Products.Handlers/
404
+
├── ProductHandler.cs
405
+
└── Middleware/ # Same linked files
406
+
└── ...
407
+
```
408
+
409
+
**Create linked files in your `.csproj`:**
410
+
411
+
```xml
412
+
<ItemGroup>
413
+
<!-- Link middleware files from Common.Middleware project -->
returnHandlerResult.ShortCircuit(Result.Invalid("Invalid order command"));
467
+
468
+
returnHandlerResult.Continue();
469
+
}
470
+
}
471
+
```
472
+
473
+
### Why This Limitation Exists
474
+
475
+
The source generator analyzes your code at compile-time to create handler wrappers with middleware baked in for maximum performance. This compile-time approach:
476
+
477
+
- ✅ Eliminates runtime reflection
478
+
- ✅ Provides strongly-typed middleware parameters
479
+
- ✅ Enables interceptors for near-direct call performance
480
+
- ❌ Requires middleware source in the same compilation
481
+
482
+
Future versions may support cross-assembly middleware discovery via metadata, but for now, linked files provide a clean workaround.
483
+
484
+
### Example: ModularMonolith Sample
485
+
486
+
See the `samples/ModularMonolithSample/` directory for a complete example of middleware in a modular architecture.
0 commit comments