DotnetDispatcher.Core 0.3.2

dotnet add package DotnetDispatcher.Core --version 0.3.2
NuGet\Install-Package DotnetDispatcher.Core -Version 0.3.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DotnetDispatcher.Core" Version="0.3.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add DotnetDispatcher.Core --version 0.3.2
#r "nuget: DotnetDispatcher.Core, 0.3.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install DotnetDispatcher.Core as a Cake Addin
#addin nuget:?package=DotnetDispatcher.Core&version=0.3.2

// Install DotnetDispatcher.Core as a Cake Tool
#tool nuget:?package=DotnetDispatcher.Core&version=0.3.2

dotnet-dispatcher 0.1

A simple dispatcher for .NET Core that uses Roslyn code generation to emit CQRS dispatcher code. Currently in extremely early stage, but I feel there's something to it.

Why?

I'm a great 'not-friend' of things like reflection, Activator and runtime type determination. When writing CQRS code, I would like to have my dispatcher code generated in compile time, with all optimalizations and other goodies that come with it.

Enter DotnetDispatcher

To generate a dispatcher is as simple as this:

using DotnetDispatcher.Attributes;
using DotnetDispatcher.Core;

namespace ConsoleTester; 

public record SampleQuery : IQuery<SampleQueryResponse>;

public record SampleQueryResponse(string Value);

[GenerateDispatcher(typeof(SampleQuery), typeof(SampleQueryHandler))]
public partial class MyAppDispatcher : DispatcherBase
{
    public MyAppDispatcher(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }
}

This will generate a dispatcher that looks like this:

namespace ConsoleTester
{
    public partial interface IMyAppDispatcher
    {
        Task<SampleQueryResponse> Dispatch(SampleQuery unit, CancellationToken cancellationToken = default);
    }
    public partial class MyAppDispatcher : IMyAppDispatcher
    {
        public Task<SampleQueryResponse> Dispatch(SampleQuery unit, CancellationToken cancellationToken = default) =>
            Get<IQueryHandler<SampleQuery, SampleQueryResponse>>().Query(unit, cancellationToken);
    }
}

Aside from the Dispatch code, a matching interface is also generated. This allows for easy mocking of the dispatcher as well as using dependency injection. You can have multiple dispatchers in a project, if you want to. Alternatively, you can repeat the use of the GenerateDispatcher attribute with other types that implement IQuery<TResponse>, ICommand<TResponse> or ICommand.

Download and install

There are three nuget packages to install:

  • DotnetDispatcher.Core - contains interfaces your commands and queries should implement, as well as the DispatcherBase class
  • DotnetDispatcher.Attributes - contains the GenerateDispatcher attribute
  • DotnetDispatcher.Generator - contains the code generator

How to use

Assuming you have an API project and a Domain project in your solution, where the generated dispatcher is part of the API project and the commands and queries are part of the Domain project:

  • The API project should reference the Domain project, as well as the DotnetDispatcher.Generator and DotnetDispatcher.Attributes packages
  • The Domain project should reference the DotnetDispatcher.Core package

The actual implementation in the projects is as such:

  • The domain project contains the query and the query handler
public record SampleQuery : IQuery<SampleQueryResponse>;

public record SampleQueryResponse(string Value);

public class SampleQueryHandler : IQueryHandler<SampleQuery, SampleQueryResponse>
{
    public Task<SampleQueryResponse> Query(SampleQuery query, CancellationToken cancellationToken = default)
    {
        return Task.FromResult(new SampleQueryResponse("nah"));
    }
}
  • The API project contains the dispatcher itself
[GenerateDispatcher(typeof(SampleQuery), typeof(SampleQueryHandler))]
public partial class MyAppDispatcher : DispatcherBase
{
    public MyAppDispatcher(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }
}

This generates the dispatcher code as well as an IServiceCollection extension method that allows you to register the dispatcher in the DI container. You can use it in the API project like this:

var serviceCollection = new ServiceCollection();

serviceCollection.RegisterMyAppDispatcherAndHandlers();

var services = serviceCollection.BuildServiceProvider();

var appDispatcher = services.GetRequiredService<IMyAppDispatcher>();
var sampleQueryResponse = await appDispatcher.Dispatch(new SampleQuery(), CancellationToken.None);

Console.WriteLine(sampleQueryResponse.Value);
Enjoy. And feel free to contribute, report bugs, give suggestions and all that good stuff.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on DotnetDispatcher.Core:

Package Downloads
DotnetDispatcher.Attributes

Attributes for DotnetDispatcher

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.2 156 1/17/2024
0.3.1 190 12/14/2023
0.3.0 227 12/3/2023
0.2.12 117 9/4/2023
0.2.11 509 8/17/2023
0.2.10 148 8/16/2023
0.2.9 247 8/4/2023
0.2.8 320 7/7/2023
0.2.7 171 6/27/2023
0.2.6 240 6/6/2023
0.2.5 201 6/2/2023
0.2.4 279 5/16/2023
0.2.3 247 4/21/2023
0.2.2 159 4/21/2023
0.2.1 262 4/8/2023
0.1.0.26 375 3/27/2023
0.1.0.24 268 3/23/2023
0.1.0.20 557 2/9/2023
0.1.0.18 309 2/8/2023
0.1.0.16 288 2/5/2023
0.1.0.14 275 2/5/2023
0.1.0.11 281 2/4/2023
0.1.0.7 262 2/4/2023