No description
Find a file
Louis Seubert cb2628c615 feat: add none generic result type
This adds a none generic result type and refactors the result to be a
class. The Result has the same inheritance like `Task` and `Task<T>`
2026-05-26 19:21:29 +02:00
.forgejo/workflows feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
src feat: add none generic result type 2026-05-26 19:21:29 +02:00
.editorconfig chore: update insert_final_newline setting 2026-05-16 12:36:35 +02:00
.gitignore feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
CHANGELOG.md chore: inital project release 2026-05-16 12:02:15 +02:00
Directory.Build.props feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
Directory.Build.targets feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
Directory.Packages.props feat: Assembly search nested handler type filtering 2026-05-23 16:17:56 +02:00
global.json feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
LICENSE.md feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
nuget.config feat: add inital in memory dispatcher 2026-05-16 11:05:07 +02:00
README.md feat: add Roslyn-based compile-time request handler registration 2026-05-23 21:25:14 +02:00
request.slnx feat: add Roslyn-based compile-time request handler registration 2026-05-23 21:25:14 +02:00

Geekeey.Request

Simple mediator implementation in .NET with minimal dependencies.

Features

  • Simple interfaces: no complex constraints, just marker interfaces that work.
  • Minmal dependencies: only depends on Microsoft.Extensions.DependencyInjection.Abstractions and the Microsoft.Extensions.Options package.

Getting Started

Install the NuGet package:

dotnet add package Geekeey.Request

You may need to add our NuGet feed to your nuget.config this can be done by running the following command:

dotnet nuget add source -n geekeey https://code.geekeey.de/api/packages/geekeey/nuget/index.json

Usage

public static Task<int> Main()
{
  var collection = new ServiceCollection();
  collection.AddRequestDispatcher(builder => builder
      .SearchHandlerInAssembly(typeof(ScalarHandler).Assembly)
      .Add(typeof(ScalarBehavior)));
  await using var provider = collection.BuildServiceProvider();
  var dispatcher = provider.GetRequiredService<IRequestDispatcher>();

  var request = new ScalarRequest { Value = "Hello" };
  var result = await dispatcher.DispatchAsync(request);

  Console.WriteLine(result);
  return 0;
}

public class ScalarRequest : IScalarRequest<string>
{
  public string Value { get; set; } = string.Empty;
}

public class ScalarHandler : IScalarRequestHandler<ScalarRequest, string>
{
  public Task<string> HandleAsync(ScalarRequest request, CancellationToken cancellationToken)
  {
    return Task.FromResult($"{request.Value} World");
  }
}

public class ScalarBehavior : IScalarRequestBehavior<ScalarRequest, string>
{
  public async Task<string> HandleAsync(ScalarRequest request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
  {
    Console.WriteLine("Before");
    var result = await next(request, cancellationToken);
    Console.WriteLine("After");
    return result;
  }
}

Compile-time registration

Projects that directly reference Geekeey.Request also get generated registration methods in the Geekeey.Request namespace:

collection.AddRequestDispatcher(builder => builder
  .AddExampleProject()
  .Add(typeof(ScalarBehavior)));

collection.AddRequestDispatcher(builder => builder
  .AddExampleProject(ServiceLifetime.Scoped)
  .Add(typeof(ScalarBehavior)));
  • generation is enabled by default
  • disable it with <CompiletimeRequestDispatchHandlerRegistration>false</CompiletimeRequestDispatchHandlerRegistration>
  • rename the generated Add<Name>(...) methods with CompiletimeRequestDispatchHandlerName
  • only request handlers are generated; behaviors still need normal registration
  • nested request handlers are rejected during Add(...) registration, including SearchHandlerInAssembly(...) and by the source generator
  • use one registration style per assembly: generated methods or SearchHandlerInAssembly(...)

Behaviour of the Handlers

Handlers are resolved from either the DI container or are created on the fly but can receive arguments from the DI container when being constructed. The same also applied for the request pipeline behaviours.