Describe the bug
Using opts.MultipleHandlerBehavior = MultipleHandlerBehavior.Separated;
With a Handler handling multiple separated messages leads to invalid code generation (and file being overwriten)
To Reproduce
Add the following test to wolverine/src/Testing/CoreTests
using System.Diagnostics;
using CoreTests.Bugs;
using JasperFx.CodeGeneration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Wolverine.Tracking;
using Xunit;
namespace CoreTests.Bugs
{
public class Bug_XXX
{
[Fact]
public async Task multiple_handler_file_overwrite()
{
using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.CodeGeneration.TypeLoadMode = TypeLoadMode.Auto;
opts.MultipleHandlerBehavior = MultipleHandlerBehavior.Separated;
})
.StartAsync();
await host.InvokeMessageAndWaitAsync(new SayStuff0());
}
}
public record SayStuff0();
public record SayStuff1(string Text);
public record SayStuff2(string Text);
public class BSayStuffHandler
{
public (SayStuff1, SayStuff2) Handle(SayStuff0 _)
{
return (new SayStuff1("Hello"), new SayStuff2("World"));
}
public void Handle(SayStuff1 stuff) => Debug.WriteLine(stuff.Text);
public void Handle(SayStuff2 stuff) => Debug.WriteLine(stuff.Text);
}
public class ASayStuffHandler
{
public void Handle(SayStuff1 stuff) => Debug.WriteLine(stuff.Text);
public void Handle(SayStuff2 stuff) => Debug.WriteLine(stuff.Text);
}
}
Run dotnet test --framework "net9.0" --filter "FullyQualifiedName=CoreTests.Bugs.Bug_XXX.multiple_handler_file_overwrite"
Watch output generated/files
Expected behavior
5 handler are created :
- 1 for SayStuff0
- 2 for SayStuff1
- 2 for SaySutff2
Actual behavior
- Because of naming conflict, the handler for SayStuff1 are overwritten :
Generated code to /wolverine/src/Testing/CoreTests/Internal/Generated/WolverineHandlers/SayStuff0Handler721297504.cs
Generated code to /wolverine/src/Testing/CoreTests/Internal/Generated/WolverineHandlers/ASayStuffHandlerHandler941180967.cs
info: CoreTests.Bugs.SayStuff1[104]
Successfully processed message CoreTests.Bugs.SayStuff1#08de4c6e-e776-240e-ca82-b5712b550000 from local://coretests.bugs.asaystuffhandler/
Generated code to /wolverine/src/Testing/CoreTests/Internal/Generated/WolverineHandlers/BSayStuffHandlerHandler1158313364.cs
info: CoreTests.Bugs.SayStuff1[104]
Successfully processed message CoreTests.Bugs.SayStuff1#08de4c6e-e776-1aa4-ca82-b5712b550000 from local://coretests.bugs.bsaystuffhandler/
Generated code to /wolverine/src/Testing/CoreTests/Internal/Generated/WolverineHandlers/BSayStuffHandlerHandler1158313364.cs
info: CoreTests.Bugs.SayStuff2[104]
Successfully processed message CoreTests.Bugs.SayStuff2#08de4c6e-e776-4150-ca82-b5712b550000 from local://coretests.bugs.bsaystuffhandler/
Generated code to /wolverine/src/Testing/CoreTests/Internal/Generated/WolverineHandlers/ASayStuffHandlerHandler941180967.cs
Notice how we write twice to ASayStuffHandlerHandler941180967
File content for more context :
// <auto-generated/>
#pragma warning disable
namespace Internal.Generated.WolverineHandlers
{
// START: ASayStuffHandlerHandler941180967
[global::System.CodeDom.Compiler.GeneratedCode("JasperFx", "1.0.0")]
public sealed class ASayStuffHandlerHandler941180967 : Wolverine.Runtime.Handlers.MessageHandler
{
public override System.Threading.Tasks.Task HandleAsync(Wolverine.Runtime.MessageContext context, System.Threading.CancellationToken cancellation)
{
// The actual message body
var sayStuff2 = (CoreTests.Bugs.SayStuff2)context.Envelope.Message;
System.Diagnostics.Activity.Current?.SetTag("message.handler", "CoreTests.Bugs.ASayStuffHandler");
var aSayStuffHandler = new CoreTests.Bugs.ASayStuffHandler();
// The actual message execution
aSayStuffHandler.Handle(sayStuff2);
return System.Threading.Tasks.Task.CompletedTask;
}
}
// END: ASayStuffHandlerHandler941180967
}
// <auto-generated/>
#pragma warning disable
namespace Internal.Generated.WolverineHandlers
{
// START: BSayStuffHandlerHandler1158313364
[global::System.CodeDom.Compiler.GeneratedCode("JasperFx", "1.0.0")]
public sealed class BSayStuffHandlerHandler1158313364 : Wolverine.Runtime.Handlers.MessageHandler
{
public override System.Threading.Tasks.Task HandleAsync(Wolverine.Runtime.MessageContext context, System.Threading.CancellationToken cancellation)
{
// The actual message body
var sayStuff2 = (CoreTests.Bugs.SayStuff2)context.Envelope.Message;
System.Diagnostics.Activity.Current?.SetTag("message.handler", "CoreTests.Bugs.BSayStuffHandler");
var bSayStuffHandler = new CoreTests.Bugs.BSayStuffHandler();
// The actual message execution
bSayStuffHandler.Handle(sayStuff2);
return System.Threading.Tasks.Task.CompletedTask;
}
}
// END: BSayStuffHandlerHandler1158313364
}
Additional context
Root cause seems to depends on the naming of the generated file which is not unique when two message in the same handler generate a separated handler (as the documentation indicates https://wolverinefx.net/guide/handlers/#multiple-handlers-for-the-same-message-type)
Describe the bug
Using
opts.MultipleHandlerBehavior = MultipleHandlerBehavior.Separated;With a Handler handling multiple separated messages leads to invalid code generation (and file being overwriten)
To Reproduce
Add the following test to
wolverine/src/Testing/CoreTestsRun
dotnet test --framework "net9.0" --filter "FullyQualifiedName=CoreTests.Bugs.Bug_XXX.multiple_handler_file_overwrite"Watch output generated/files
Expected behavior
5 handler are created :
Actual behavior
Notice how we write twice to
ASayStuffHandlerHandler941180967File content for more context :
Additional context
Root cause seems to depends on the naming of the generated file which is not unique when two message in the same handler generate a separated handler (as the documentation indicates https://wolverinefx.net/guide/handlers/#multiple-handlers-for-the-same-message-type)