Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
93fa154
refactor(application): decorate handlers directly instead of relying …
Vulthil May 25, 2026
fc554fe
feat(messaging): harden RabbitMQ transport and add config-driven setup
Vulthil May 25, 2026
ab8eaba
feat(messaging): add IConsumeFilter<TMessage> pipeline for consumer c…
Vulthil May 25, 2026
fa8ff73
feat(messaging): add LoggingConsumeFilter as default opt-out filter
Vulthil May 25, 2026
139c82b
refactor(messaging): merge options/provider behind dual interfaces an…
Vulthil May 25, 2026
000a641
feat(messaging): add point-to-point ISendEndpoint with ctx.SendAsync
Vulthil May 25, 2026
4112353
refactor(messaging): collapse consumer invokers into MessageHandler +…
Vulthil May 26, 2026
98dcc1d
feat(messaging): wrap publishes in MessageEnvelope and key dispatch b…
Vulthil May 28, 2026
faeacb4
refactor(messaging): consolidate routing-key config; nullable Subscribe
Vulthil May 29, 2026
eae2c14
feat(messaging): support per-request timeout via IRequestContext
Vulthil May 30, 2026
ae5f51d
test(messaging): expand integration scenarios and add failure-config …
Vulthil May 30, 2026
e35450e
docs: remove placeholder XML doc boilerplate across src, tests, and s…
Vulthil May 30, 2026
a81ec69
feat(messaging): per-aggregate ordering via UsePartitioner
Vulthil May 31, 2026
dc24d8b
feat(messaging): add in-memory retry mode preserving per-key order on…
Vulthil May 31, 2026
bc0f1d5
feat(messaging): single active consumer for cross-instance ordering
Vulthil Jun 1, 2026
e47519a
feat(messaging): add CorrelationId-keyed UsePartitioner overloads
Vulthil Jun 1, 2026
ef7865d
Merged main into branch
Vulthil Jun 1, 2026
4d5ed3a
fix(messaging): correlate RPC on RequestId, envelope replies, enable …
Vulthil Jun 1, 2026
c4f4653
Merge branch 'main' of https://github.com/Vulthil/Vulthil.SharedKerne…
Vulthil Jun 1, 2026
f9e23ce
Fixed warnings in build
Vulthil Jun 1, 2026
49db951
fix(messaging): serialize consumer channel writes on partitioned queues
Vulthil Jun 2, 2026
ba5467d
fix(messaging): advance in-memory RetryCount; make consume Headers re…
Vulthil Jun 3, 2026
5b6cdd0
refactor(messaging): internalize configurator impls; align UseRetry n…
Vulthil Jun 3, 2026
6aa0997
refactor(messaging): typed Fault.OriginalContext snapshot; drop Null*…
Vulthil Jun 3, 2026
f37bfc9
refactor(messaging): promote envelope, pipeline factory, handler kind…
Vulthil Jun 3, 2026
dc4197c
refactor(messaging): extract generic MessageExecutionRegistry; Rabbit…
Vulthil Jun 4, 2026
b028d03
refactor(messaging): make IPublishContext write-only via Set methods;…
Vulthil Jun 4, 2026
e988532
refactor(messaging): make publish context and envelope factory public
Vulthil Jun 4, 2026
3a7f484
refactor(messaging): add public envelope-based message context builder
Vulthil Jun 4, 2026
e29995a
feat(messaging): make QueueDefinition consumer/subscription registrat…
Vulthil Jun 4, 2026
d165661
test(messaging): cover transport primitives in core test project
Vulthil Jun 4, 2026
eb9ee37
refactor(messaging): build RabbitMq test providers via public AddMess…
Vulthil Jun 4, 2026
0694f89
docs(messaging): document writing a custom transport
Vulthil Jun 4, 2026
ed5a3c8
Merge remote-tracking branch 'origin/main' into feature/messaging-har…
Vulthil Jun 4, 2026
c7b539b
feat(messaging): bounded publish channel pool with RabbitMq transport…
Vulthil Jun 4, 2026
ee26cb4
test: add BaseUnitTestCase teardown hook; adopt Target and ctor mock-…
Vulthil Jun 4, 2026
45451ae
test(messaging): drive consume-filter and polymorphic dispatch tests …
Vulthil Jun 5, 2026
12bf5a6
feat(messaging): publish Fault<T> to the fault exchange by convention…
Vulthil Jun 5, 2026
51506b1
build(aspire): centralize SDK version in global.json and bump Aspire …
Vulthil Jun 5, 2026
6217b3d
feat(messaging): add in-memory ITestHarness transport on the public T…
Vulthil Jun 5, 2026
3bbecd4
Merge branch 'claude/sleepy-stonebraker-d53eef' into feature/messagin…
Vulthil Jun 5, 2026
e959ffe
fix(messaging): round-trip queue: URIs through PublishContext address…
Vulthil Jun 5, 2026
2bec04b
test(messaging): add Fault and MessageContextSnapshot tests for Abstr…
Vulthil Jun 5, 2026
06676cd
Try updating scripts
Vulthil Jun 5, 2026
6aa36b3
test(messaging): pin integration test HttpClients to the http endpoin…
Vulthil Jun 6, 2026
e14ff05
added the runner props
Vulthil Jun 6, 2026
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
15 changes: 15 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# Copilot Instructions

## Git Guidelines
- Do not commit without an explicit permission. Allow the developers a change to review the code to provide feedback before commiting.
- Do not create commit descriptions. Only suggest the one line commit message that describes the change.

## Project Guidelines
- Use a lazy `Target` pattern from `CreateInstance<T>` when inheriting from `BaseUnitTestCase` (or `BaseUnitTestCase<T>` when accessibility allows) for test classes in this repository.
- When modifying a public member, make sure to update the XML Documentation and the corresponding docs in the docs folder and the README file if applicable.
- When modifying a public member, make sure to check the Public.API files for the affected assembly and update them if necessary.
- Do not ignore CS1591 warnings; analyze and add missing XML comments instead.
- Do not add comments inside methods; for complex logic, consider extracting it into a separate method with a descriptive name instead of adding comments.

## Testing Guidelines
- Prefer using the Vulthil.xUnit testing framework for tests.
- When writing tests, follow the Arrange-Act-Assert pattern for better readability and maintainability.
- Prefer using the BaseUnitTestCase or BaseUnitTestCase<T> classes for test cases to leverage common setup and utilities.
- Prefer using the `CancellationToken` property on the base test classes, instead of getting the `TestContext.Current.CancellationToken` directly.
- Prefer using the AutoMocker instance for dependency injection in tests to simplify test setup and improve readability.
- Use the methods on the BaseUnitTestCase class for modifying the AutoMocker instance, such as `Use<T>(T instance)` or `Use<T>()` for registering dependencies, and `GetMock<T>()` for retrieving mocks from the AutoMocker.
- Override the CreateInstance or CreateInstance<T> methods and use the Target property to lazily create the instance under test.
- Do not add comments inside test methods except Arrange, Act and Assert; rename the test method to be descriptive of the behavior being tested instead of adding comments.

## Documentation Guidelines
- When generating package README files, keep them short and concise, and use the docs folder for more elaborate usage patterns.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ apply-to: "src/**/*.*"
When assisting with this C# solution, you MUST adhere to the following documentation standards for all code modifications, additions, and refactors. Failure to maintain these standards will result in build warnings, CI/CD failures, or degraded documentation.

## 1. XML Documentation for Public Members
All `public` types and members (classes, structs, interfaces, records, enums, methods, properties, events, and fields) REQUIRE standard C# XML documentation comments (`///`).
Add standard C# XML documentation comments (`///`) only where the compiler would otherwise emit **CS1591** ("Missing XML comment for publicly visible type or member").
In practice this covers `public` types and members (classes, structs, interfaces, records, enums, methods, properties, events, and fields) in assemblies that generate a documentation file.
Do not add `///` comments to members the compiler does not warn about (e.g., `internal`, `private`, or `protected` members, or members already covered by an enclosing `<inheritdoc />`),
as this adds noise without satisfying any analyzer requirement.

* **Required Tags:** Always include a `<summary>`.
* **Contextual Tags:** Include `<param>`, `<returns>`, `<value>`, `<remarks>`, and `<exception>` tags wherever applicable.
Expand All @@ -33,7 +36,7 @@ The conceptual documentation is housed in the `docs` folder and is built using D

## Agent Verification Checklist
Before completing your task, verify the following:
- [ ] Did I add `///` comments to all newly created or modified `public` members?
- [ ] Did I add `///` comments to every newly created or modified member that would otherwise trigger CS1591 (and avoid adding them where the compiler does not warn)?
- [ ] Did I add the exact API signature to `PublicAPI.Unshipped.txt`?
- [ ] Did I add/update usage examples in the `docs` folder?
- [ ] Are my conceptual doc changes compatible with `docs/docfx.json` and the Table of Contents?
3 changes: 1 addition & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PropertyGroup>
<FrameworkVersion>10.0.8</FrameworkVersion>
<FrameworkVersion Condition="'$(TargetFramework)' == 'net9.0'">9.0.16</FrameworkVersion>
<AspireVersion>13.3.5</AspireVersion>
<AspireVersion>13.4.2</AspireVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="$(AspireVersion)" />
Expand Down Expand Up @@ -53,7 +53,6 @@
<PackageVersion Include="Respawn" Version="7.0.0" />
<PackageVersion Include="Scalar.Aspire" Version="0.9.37" />
<PackageVersion Include="Scalar.AspNetCore" Version="2.11.6" />
<PackageVersion Include="Scrutor" Version="7.0.0" />
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="SonarAnalyzer.CSharp" Version="10.27.0.140913" />
<PackageVersion Include="Testcontainers" Version="4.12.0" />
Expand Down
6 changes: 5 additions & 1 deletion Vulthil.SharedKernel.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<File Path=".github/dependabot.yml" />
</Folder>
<Folder Name="/.github/instructions/">
<File Path=".github/instructions/documentation-guidelines.instructions.md" />
<File Path=".github/instructions/style-guidelines.instructions.md" />
<File Path="documentation-guidelines.instructions.md" />
</Folder>
<Folder Name="/.github/workflows/">
<File Path=".github/workflows/ci.yml" />
Expand Down Expand Up @@ -44,6 +44,8 @@
<File Path=".editorconfig" />
<File Path=".gitattributes" />
<File Path=".gitignore" />
<File Path="CLAUDE.md" />
<File Path="cliff.toml" />
<File Path="Directory.Build.props" />
<File Path="Directory.Packages.props" />
<File Path="global.json" />
Expand Down Expand Up @@ -83,6 +85,7 @@
<Folder Name="/tests/">
<Project Path="tests/Vulthil.Messaging.Abstractions.Tests/Vulthil.Messaging.Abstractions.Tests.csproj" />
<Project Path="tests/Vulthil.Messaging.RabbitMq.Tests/Vulthil.Messaging.RabbitMq.Tests.csproj" />
<Project Path="tests/Vulthil.Messaging.TestHarness.Tests/Vulthil.Messaging.TestHarness.Tests.csproj" />
<Project Path="tests/Vulthil.Messaging.Tests/Vulthil.Messaging.Tests.csproj" />
<Project Path="tests/Vulthil.Results.Tests/Vulthil.Results.Tests.csproj" />
<Project Path="tests/Vulthil.SharedKernel.Application.Tests/Vulthil.SharedKernel.Application.Tests.csproj" />
Expand All @@ -100,5 +103,6 @@
</Folder>
<Folder Name="/tests/Test Items/">
<File Path="tests/Directory.Build.props" />
<File Path="tests/Vulthil.TestRunner.props" />
</Folder>
</Solution>
25 changes: 25 additions & 0 deletions docs/articles/cqrs-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,28 @@ app.MapPost("/users", async (CreateUserCommand command, ISender sender) =>
return result.ToIResult();
});
```

### Direct handler injection

You can also inject the handler interface directly. The resolved instance is the same pipeline-wrapped handler that `ISender` would dispatch to, so behaviors (validation, logging, transactions, custom ones) apply uniformly either way.

```csharp
app.MapPost("/users", async (
CreateUserCommand command,
ICommandHandler<CreateUserCommand, Result<Guid>> handler) =>
{
var result = await handler.HandleAsync(command);
return result.ToIResult();
});
```

The interfaces you can inject are `IHandler<TRequest, TResponse>`, `ICommandHandler<TCommand, TResponse>`, `ICommandHandler<TCommand>` (for `Result`-returning commands) and `IQueryHandler<TQuery, TResponse>`. The concrete handler implementation is *not* registered as a DI service β€” there is no way to bypass the pipeline by injecting the concrete type.

## Behaviors across assemblies

Pipeline behaviors are composed at handler-resolution time, not at registration time, so the order of registration is irrelevant. Different assemblies may register handlers and behaviors independently β€” all behaviors registered before `BuildServiceProvider` apply to all handlers resolved afterwards.

```csharp
// In an Infrastructure assembly:
services.AddOpenPipelineHandler(typeof(MyCustomBehavior<,>));
```
Loading