SSWConsulting/SSW.VerticalSliceArchitecture

♻️ Move to Immediate.Handlers

viceroypenguin opened this issue · 10 comments

Immediate.Handlers is an improved way of dealing with the command/dispatch pattern; both for clarity of dependency relationship, and for performance.

Example VSA Template using it: https://github.com/viceroypenguin/VsaTemplate/tree/master/Web

Would love to hear your opinion on it, and whether you think it's useful for your template.

Hona commented

Hi @viceroypenguin, thanks for the issue :)

I've seen you link & talk about it on the discord, I've been meaning to check it out, and I will do so

Hona commented

@viceroypenguin

I've triaged this to be in the next release :)

Awesome! If you wait another day or two, I'm also working on Immediate.Apis, which will automate registration of [Handler]s that have [MapGet] (or post, put, patch, delete) with Minimal APIs

Hona commented

Yeah I saw you release that, I believe theres a few source generated endpoint mappings. Whats the difference between Immediate.Apis and the few examples below? Are both your Immediate packages AOT compatible?

https://github.com/davidfowl/uController
https://github.com/joaofbantunes/RegisteringMinimalApisWithSourceGeneratorsSample

I assume it is the whole end to end of interface + wiring up to the generic host?

https://github.com/joaofbantunes/RegisteringMinimalApisWithSourceGeneratorsSample

I would recommend against this one generally because it uses ISourceGenerator and hasn't been updated to IIncrementalGenerator. There are some pretty steep performance differences between the two, which make anything still using ISourceGenerator a disrecommendation.

https://github.com/davidfowl/uController

Same for this one.

Goal of Immediate.Apis

Register the following:

using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;
using Microsoft.AspNetCore.Authorization;

namespace Immediate.Apis.FunctionalTests.Features.WeatherForecast;

[Handler]
[MapGet("/forecast")]
[AllowAnonymous]
public static partial class Get
{
	public sealed record Query;

	public sealed record Result
	{
		public required DateOnly Date { get; init; }
		public required int TemperatureC { get; init; }
		public required string? Summary { get; init; }
		public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
	}

	private static async ValueTask<IReadOnlyList<Result>> Handle(
		Query _,
		CancellationToken token
	)
	{
		await Task.Delay(1, token);
		return [
			new() { Date = new(2024, 1, 1), TemperatureC = 0, Summary = "Sunny and Freezing" },
		];
	}
}

by adding the following:

using Microsoft.AspNetCore.Mvc;

#pragma warning disable CS1591

namespace Microsoft.AspNetCore.Builder;

public static class ImmediateApisFunctionalTestsRoutesBuilder
{
	public static IEndpointRouteBuilder MapImmediateApisFunctionalTestsEndpoints(
		this IEndpointRouteBuilder app
	)
	{
		_ = app
			.MapGet(
				"/forecast",
				async (
					[AsParameters] global::Immediate.Apis.FunctionalTests.Features.WeatherForecast.Get.Query parameters,
					[FromServices] global::Immediate.Apis.FunctionalTests.Features.WeatherForecast.Get.Handler handler,
					CancellationToken token
				) => await handler.HandleAsync(parameters, token)
			)
		    .AllowAnonymous()
			;

		return app;
	}
}

I have not tested, but both should be AOT compatible, because there's no reflection or dynamic type analysis done.

Hona commented

Interesting - thank you for the example. I'll give this one a good look & try it out as well :)

Hona commented

BTW - if you're keen to contribute - I'd be happy to accept a PR moving from MediatR requests to Immediate.Handlers if you've got the time. Otherwise I'll action it myself

BTW - if you're keen to contribute - I'd be happy to accept a PR moving from MediatR requests to Immediate.Handlers if you've got the time. Otherwise I'll action it myself

I wish I did have the time. Unfortunately, I've got too many projects on my plate already, before I cursed myself by releasing two source generator projects. 😂

Besides, I need feedback from users other than myself on how well they work. :)

Hona commented

Perfect - I'll give you any feedback once I have a working version

Hona commented

Done - moved to immediate.handlers. Immediate APIs will be tracked in another issue/PR. (e.g. #62)