From 75436b1fa37cdfe9fa0478ddbf0b4aa7c6f23bb7 Mon Sep 17 00:00:00 2001 From: joshkempner Date: Thu, 28 May 2026 15:41:36 -0400 Subject: [PATCH 1/2] Fixes PR build check for formatting --- .github/workflows/pr-checks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 00a65c3d..6737e510 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -78,4 +78,5 @@ jobs: # Format - name: Check Formatting + working-directory: src run: dotnet format ReactiveDomain.sln --verify-no-changes --no-restore \ No newline at end of file From 78fed1b922f49e6d4ae7ce7720be5937eeb61247 Mon Sep 17 00:00:00 2001 From: joshkempner Date: Thu, 28 May 2026 15:58:13 -0400 Subject: [PATCH 2/2] Changes line endings in two files that failed format checks --- .../when_using_read_model_base.cs | 416 +++++++++--------- .../when_rebuilding_message_hierarchy.cs | 184 ++++---- 2 files changed, 300 insertions(+), 300 deletions(-) diff --git a/src/ReactiveDomain.Foundation.Tests/when_using_read_model_base.cs b/src/ReactiveDomain.Foundation.Tests/when_using_read_model_base.cs index 27a5a0b6..ae515fe2 100644 --- a/src/ReactiveDomain.Foundation.Tests/when_using_read_model_base.cs +++ b/src/ReactiveDomain.Foundation.Tests/when_using_read_model_base.cs @@ -1,208 +1,208 @@ -using System; -using ReactiveDomain.Messaging; -using ReactiveDomain.Messaging.Bus; -using ReactiveDomain.Testing; -using Xunit; - -namespace ReactiveDomain.Foundation.Tests; - -// ReSharper disable once InconsistentNaming -public class when_using_read_model_base : - ReadModelBase, - IHandle, - IClassFixture { - - private static IStreamStoreConnection _conn; - private static readonly IEventSerializer Serializer = - new JsonMessageSerializer(); - private static readonly IStreamNameBuilder Namer = - new PrefixedCamelCaseStreamNameBuilder(nameof(when_using_read_model_base)); - - private readonly string _stream1; - private readonly string _stream2; - - - public when_using_read_model_base(StreamStoreConnectionFixture fixture) - : base(nameof(when_using_read_model_base), new ConfiguredConnection(fixture.Connection, Namer, Serializer)) { - _conn = fixture.Connection; - _conn.Connect(); - - // ReSharper disable once RedundantTypeArgumentsOfMethod - EventStream.Subscribe(this); - - _stream1 = Namer.GenerateForAggregate(typeof(TestAggregate), Guid.NewGuid()); - _stream2 = Namer.GenerateForAggregate(typeof(TestAggregate), Guid.NewGuid()); - - AppendEvents(10, _conn, _stream1, 2); - AppendEvents(10, _conn, _stream2, 3); - - _conn.TryConfirmStream(_stream1, 10); - _conn.TryConfirmStream(_stream2, 10); - _conn.TryConfirmStream(Namer.GenerateForCategory(typeof(TestAggregate)), 20); - } - - private void AppendEvents( - int numEventsToBeSent, - IStreamStoreConnection conn, - string streamName, - int value) { - for (int evtNumber = 0; evtNumber < numEventsToBeSent; evtNumber++) { - var evt = new ReadModelTestEvent(evtNumber, value); - conn.AppendToStream(streamName, ExpectedVersion.Any, null, Serializer.Serialize(evt)); - } - } - [Fact] - public void can_start_streams_by_aggregate() { - var aggId = Guid.NewGuid(); - var s1 = Namer.GenerateForAggregate(typeof(TestAggregate), aggId); - AppendEvents(1, _conn, s1, 7); - Start(aggId); - AssertEx.AtLeastModelVersion(this, 2, msg: $"Expected 2 got {Version}"); // 1 message + CatchupSubscriptionBecameLive - AssertEx.IsOrBecomesTrue(() => Sum == 7); - } - [Fact] - public void can_start_streams_by_aggregate_category() { - - var s1 = Namer.GenerateForAggregate(typeof(ReadModelTestCategoryAggregate), Guid.NewGuid()); - AppendEvents(1, _conn, s1, 7); - var s2 = Namer.GenerateForAggregate(typeof(ReadModelTestCategoryAggregate), Guid.NewGuid()); - AppendEvents(1, _conn, s2, 5); - Start(null, true); - - AssertEx.AtLeastModelVersion(this, 3, msg: $"Expected 3 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 12); - } - [Fact] - public void can_read_one_stream() { - Start(_stream1); - AssertEx.AtLeastModelVersion(this, 11, msg: $"Expected 11 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 20); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(9, GetCheckpoint()[0].Item2); - } - [Fact] - public void can_read_two_streams() { - Start(_stream1); - Start(_stream2); - AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 50); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(9, GetCheckpoint()[0].Item2); - Assert.Equal(_stream2, GetCheckpoint()[1].Item1); - Assert.Equal(9, GetCheckpoint()[1].Item2); - } - [Fact] - public void can_wait_for_one_stream_to_go_live() { - Start(_stream1, null, true); - AssertEx.AtLeastModelVersion(this, 11, TimeSpan.FromMilliseconds(100), msg: $"Expected 11 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 20, 100); - } - [Fact] - public void can_wait_for_two_streams_to_go_live() { - Start(_stream1, null, true); - AssertEx.AtLeastModelVersion(this, 11, TimeSpan.FromMilliseconds(100), msg: $"Expected 11 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 20, 150); - - Start(_stream2, null, true); - AssertEx.AtLeastModelVersion(this, 21, TimeSpan.FromMilliseconds(100), msg: $"Expected 21 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 50, 150); - } - [Fact] - public void can_listen_to_one_stream() { - Start(_stream1); - AssertEx.AtLeastModelVersion(this, 11, msg: $"Expected 11 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 20); - //add more messages - AppendEvents(10, _conn, _stream1, 5); - AssertEx.AtLeastModelVersion(this, 21, msg: $"Expected 21 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 70); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(19, GetCheckpoint()[0].Item2); - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(19, GetCheckpoint()[0].Item2); - } - [Fact] - public void can_listen_to_two_streams() { - Start(_stream1); - Start(_stream2); - AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 50); - //add more messages - AppendEvents(10, _conn, _stream1, 5); - AppendEvents(10, _conn, _stream2, 7); - AssertEx.AtLeastModelVersion(this, 42, msg: $"Expected 42 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 170); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(19, GetCheckpoint()[0].Item2); - Assert.Equal(_stream2, GetCheckpoint()[1].Item1); - Assert.Equal(19, GetCheckpoint()[1].Item2); - } - [Fact] - public void can_use_checkpoint_on_one_stream() { - //restore state - var checkPoint = 8L;//Zero based, ignore the first 9 events - Sum = 18; - //start at the checkpoint - Start(_stream1, checkPoint); - //add the one recorded event - AssertEx.AtLeastModelVersion(this, 2, TimeSpan.FromMilliseconds(100), msg: $"Expected 2 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 20); - //add more messages - AppendEvents(10, _conn, _stream1, 5); - AssertEx.AtLeastModelVersion(this, 3, TimeSpan.FromMilliseconds(200), msg: $"Expected 3 got {Version}"); - AssertEx.AtLeastModelVersion(this, 8, TimeSpan.FromMilliseconds(100), msg: $"Expected 8 got {Version}"); - AssertEx.AtLeastModelVersion(this, 12, TimeSpan.FromMilliseconds(100), msg: $"Expected 12 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 70); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(19, GetCheckpoint()[0].Item2); - } - [Fact] - public void can_use_checkpoint_on_two_streams() { - //restore state - var checkPoint1 = 8L;//Zero based, ignore the first 9 events - var checkPoint2 = 5L;//Zero based, ignore the first 6 events - Sum = (9 * 2) + (6 * 3); - Start(_stream1, checkPoint1); - Start(_stream2, checkPoint2); - //add the recorded events 2 on stream 1 & 5 on stream 2 - AssertEx.AtLeastModelVersion(this, 7, msg: $"Expected 7 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 50, msg: $"Expected 50 got {Sum}"); - //add more messages - AppendEvents(10, _conn, _stream1, 5); - AppendEvents(10, _conn, _stream2, 7); - AssertEx.AtLeastModelVersion(this, 27, msg: $"Expected 27 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 170); - //confirm checkpoints - Assert.Equal(_stream1, GetCheckpoint()[0].Item1); - Assert.Equal(19, GetCheckpoint()[0].Item2); - Assert.Equal(_stream2, GetCheckpoint()[1].Item1); - Assert.Equal(19, GetCheckpoint()[1].Item2); - } - [Fact] - public void can_listen_to_the_same_stream_twice() { - Assert.Equal(0, Version); - //weird but true - //n.b. Don't do this on purpose - Start(_stream1); - Start(_stream1); - //double events - AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 40); - //even more doubled events - AppendEvents(10, _conn, _stream1, 5); - AssertEx.AtLeastModelVersion(this, 42, TimeSpan.FromSeconds(2), msg: $"Expected 42 got {Version}"); - AssertEx.IsOrBecomesTrue(() => Sum == 140); - } - - public long Sum { get; private set; } - void IHandle.Handle(ReadModelTestEvent @event) { - Sum += @event.Value; - } - public record ReadModelTestEvent(int Number, int Value) : Event; - public class ReadModelTestCategoryAggregate : EventDrivenStateMachine; -} +using System; +using ReactiveDomain.Messaging; +using ReactiveDomain.Messaging.Bus; +using ReactiveDomain.Testing; +using Xunit; + +namespace ReactiveDomain.Foundation.Tests; + +// ReSharper disable once InconsistentNaming +public class when_using_read_model_base : + ReadModelBase, + IHandle, + IClassFixture { + + private static IStreamStoreConnection _conn; + private static readonly IEventSerializer Serializer = + new JsonMessageSerializer(); + private static readonly IStreamNameBuilder Namer = + new PrefixedCamelCaseStreamNameBuilder(nameof(when_using_read_model_base)); + + private readonly string _stream1; + private readonly string _stream2; + + + public when_using_read_model_base(StreamStoreConnectionFixture fixture) + : base(nameof(when_using_read_model_base), new ConfiguredConnection(fixture.Connection, Namer, Serializer)) { + _conn = fixture.Connection; + _conn.Connect(); + + // ReSharper disable once RedundantTypeArgumentsOfMethod + EventStream.Subscribe(this); + + _stream1 = Namer.GenerateForAggregate(typeof(TestAggregate), Guid.NewGuid()); + _stream2 = Namer.GenerateForAggregate(typeof(TestAggregate), Guid.NewGuid()); + + AppendEvents(10, _conn, _stream1, 2); + AppendEvents(10, _conn, _stream2, 3); + + _conn.TryConfirmStream(_stream1, 10); + _conn.TryConfirmStream(_stream2, 10); + _conn.TryConfirmStream(Namer.GenerateForCategory(typeof(TestAggregate)), 20); + } + + private void AppendEvents( + int numEventsToBeSent, + IStreamStoreConnection conn, + string streamName, + int value) { + for (int evtNumber = 0; evtNumber < numEventsToBeSent; evtNumber++) { + var evt = new ReadModelTestEvent(evtNumber, value); + conn.AppendToStream(streamName, ExpectedVersion.Any, null, Serializer.Serialize(evt)); + } + } + [Fact] + public void can_start_streams_by_aggregate() { + var aggId = Guid.NewGuid(); + var s1 = Namer.GenerateForAggregate(typeof(TestAggregate), aggId); + AppendEvents(1, _conn, s1, 7); + Start(aggId); + AssertEx.AtLeastModelVersion(this, 2, msg: $"Expected 2 got {Version}"); // 1 message + CatchupSubscriptionBecameLive + AssertEx.IsOrBecomesTrue(() => Sum == 7); + } + [Fact] + public void can_start_streams_by_aggregate_category() { + + var s1 = Namer.GenerateForAggregate(typeof(ReadModelTestCategoryAggregate), Guid.NewGuid()); + AppendEvents(1, _conn, s1, 7); + var s2 = Namer.GenerateForAggregate(typeof(ReadModelTestCategoryAggregate), Guid.NewGuid()); + AppendEvents(1, _conn, s2, 5); + Start(null, true); + + AssertEx.AtLeastModelVersion(this, 3, msg: $"Expected 3 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 12); + } + [Fact] + public void can_read_one_stream() { + Start(_stream1); + AssertEx.AtLeastModelVersion(this, 11, msg: $"Expected 11 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 20); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(9, GetCheckpoint()[0].Item2); + } + [Fact] + public void can_read_two_streams() { + Start(_stream1); + Start(_stream2); + AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 50); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(9, GetCheckpoint()[0].Item2); + Assert.Equal(_stream2, GetCheckpoint()[1].Item1); + Assert.Equal(9, GetCheckpoint()[1].Item2); + } + [Fact] + public void can_wait_for_one_stream_to_go_live() { + Start(_stream1, null, true); + AssertEx.AtLeastModelVersion(this, 11, TimeSpan.FromMilliseconds(100), msg: $"Expected 11 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 20, 100); + } + [Fact] + public void can_wait_for_two_streams_to_go_live() { + Start(_stream1, null, true); + AssertEx.AtLeastModelVersion(this, 11, TimeSpan.FromMilliseconds(100), msg: $"Expected 11 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 20, 150); + + Start(_stream2, null, true); + AssertEx.AtLeastModelVersion(this, 21, TimeSpan.FromMilliseconds(100), msg: $"Expected 21 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 50, 150); + } + [Fact] + public void can_listen_to_one_stream() { + Start(_stream1); + AssertEx.AtLeastModelVersion(this, 11, msg: $"Expected 11 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 20); + //add more messages + AppendEvents(10, _conn, _stream1, 5); + AssertEx.AtLeastModelVersion(this, 21, msg: $"Expected 21 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 70); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(19, GetCheckpoint()[0].Item2); + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(19, GetCheckpoint()[0].Item2); + } + [Fact] + public void can_listen_to_two_streams() { + Start(_stream1); + Start(_stream2); + AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 50); + //add more messages + AppendEvents(10, _conn, _stream1, 5); + AppendEvents(10, _conn, _stream2, 7); + AssertEx.AtLeastModelVersion(this, 42, msg: $"Expected 42 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 170); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(19, GetCheckpoint()[0].Item2); + Assert.Equal(_stream2, GetCheckpoint()[1].Item1); + Assert.Equal(19, GetCheckpoint()[1].Item2); + } + [Fact] + public void can_use_checkpoint_on_one_stream() { + //restore state + var checkPoint = 8L;//Zero based, ignore the first 9 events + Sum = 18; + //start at the checkpoint + Start(_stream1, checkPoint); + //add the one recorded event + AssertEx.AtLeastModelVersion(this, 2, TimeSpan.FromMilliseconds(100), msg: $"Expected 2 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 20); + //add more messages + AppendEvents(10, _conn, _stream1, 5); + AssertEx.AtLeastModelVersion(this, 3, TimeSpan.FromMilliseconds(200), msg: $"Expected 3 got {Version}"); + AssertEx.AtLeastModelVersion(this, 8, TimeSpan.FromMilliseconds(100), msg: $"Expected 8 got {Version}"); + AssertEx.AtLeastModelVersion(this, 12, TimeSpan.FromMilliseconds(100), msg: $"Expected 12 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 70); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(19, GetCheckpoint()[0].Item2); + } + [Fact] + public void can_use_checkpoint_on_two_streams() { + //restore state + var checkPoint1 = 8L;//Zero based, ignore the first 9 events + var checkPoint2 = 5L;//Zero based, ignore the first 6 events + Sum = (9 * 2) + (6 * 3); + Start(_stream1, checkPoint1); + Start(_stream2, checkPoint2); + //add the recorded events 2 on stream 1 & 5 on stream 2 + AssertEx.AtLeastModelVersion(this, 7, msg: $"Expected 7 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 50, msg: $"Expected 50 got {Sum}"); + //add more messages + AppendEvents(10, _conn, _stream1, 5); + AppendEvents(10, _conn, _stream2, 7); + AssertEx.AtLeastModelVersion(this, 27, msg: $"Expected 27 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 170); + //confirm checkpoints + Assert.Equal(_stream1, GetCheckpoint()[0].Item1); + Assert.Equal(19, GetCheckpoint()[0].Item2); + Assert.Equal(_stream2, GetCheckpoint()[1].Item1); + Assert.Equal(19, GetCheckpoint()[1].Item2); + } + [Fact] + public void can_listen_to_the_same_stream_twice() { + Assert.Equal(0, Version); + //weird but true + //n.b. Don't do this on purpose + Start(_stream1); + Start(_stream1); + //double events + AssertEx.AtLeastModelVersion(this, 22, msg: $"Expected 22 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 40); + //even more doubled events + AppendEvents(10, _conn, _stream1, 5); + AssertEx.AtLeastModelVersion(this, 42, TimeSpan.FromSeconds(2), msg: $"Expected 42 got {Version}"); + AssertEx.IsOrBecomesTrue(() => Sum == 140); + } + + public long Sum { get; private set; } + void IHandle.Handle(ReadModelTestEvent @event) { + Sum += @event.Value; + } + public record ReadModelTestEvent(int Number, int Value) : Event; + public class ReadModelTestCategoryAggregate : EventDrivenStateMachine; +} diff --git a/src/ReactiveDomain.Messaging.Tests/when_rebuilding_message_hierarchy.cs b/src/ReactiveDomain.Messaging.Tests/when_rebuilding_message_hierarchy.cs index 2fbf9288..4dcc91a0 100644 --- a/src/ReactiveDomain.Messaging.Tests/when_rebuilding_message_hierarchy.cs +++ b/src/ReactiveDomain.Messaging.Tests/when_rebuilding_message_hierarchy.cs @@ -1,92 +1,92 @@ -using System; -using System.IO; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace ReactiveDomain.Messaging.Tests; - -// ReSharper disable InconsistentNaming -public sealed class when_rebuilding_message_hierarchy : IDisposable { - private string _filePath; - sealed class TestMsg : IMessage { - public Guid MsgId { get; private set; } - public TestMsg() { - MsgId = Guid.NewGuid(); - } - } - private void LoadDynamicAssembly() { - var needed = new[] { - "mscorlib", - "netstandard", - "Newtonsoft.Json", - "System", - "System.Core", - "Microsoft.CSharp", - "ReactiveDomain.Messaging", - "ReactiveDomain.Core", - "System.Numerics", - "System.Xml" - }; - - var assemblies = (AppDomain.CurrentDomain - .GetAssemblies() - .Where(reference => needed.Contains(reference.GetName().Name, StringComparer.OrdinalIgnoreCase)) - .Select(reference => reference.Location)).Select(file => (MetadataReference)MetadataReference.CreateFromFile(file)).ToArray(); - - var compilation = CSharpCompilation.Create("TestDynamicAssembly") - .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) - .AddReferences(assemblies) - .AddSyntaxTrees(CSharpSyntaxTree.ParseText( - @"using ReactiveDomain.Messaging; namespace SimpleMsg { public class DynamicMessage : Message { } }")); - - _filePath = AppDomain.CurrentDomain.BaseDirectory + $"\\TestDynamicAssembly{Guid.NewGuid()}.dll"; - - var emitResult = compilation.Emit(_filePath); - if (!emitResult.Success) { - foreach (var diagnostic in emitResult.Diagnostics) { - Console.WriteLine(diagnostic.ToString()); - } - } - - byte[] buffer = File.ReadAllBytes(_filePath); - - AppDomain.CurrentDomain.Load(buffer); - - } - /* Flaky Test //todo: evaluate if we still need this. -#if(NET48) - [Fact] - public void can_dynamically_add_types_without_clearing_handlers() - { - - var bus = InMemoryBus.CreateTest(); - - var fired = false; - bus.Subscribe(new AdHocHandler(m => fired = true)); - - bus.Publish(new TestMsg()); - Assert.True(fired); - - LoadDynamicAssembly(); - var messageType = MessageHierarchy.GetTypeByName("DynamicMessage"); - Assert.Equal("DynamicMessage", messageType[0].Name); - Assert.True(messageType.Count == 1); - - fired = false; - bus.Publish(new TestMsg()); - AssertEx.IsOrBecomesTrue(() => fired); - } -#endif - */ - public void Dispose() { - if (!File.Exists(_filePath)) - return; - try { - File.Delete(_filePath); - } catch { - // ignored - } - } -} -// ReSharper restore InconsistentNaming +using System; +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace ReactiveDomain.Messaging.Tests; + +// ReSharper disable InconsistentNaming +public sealed class when_rebuilding_message_hierarchy : IDisposable { + private string _filePath; + sealed class TestMsg : IMessage { + public Guid MsgId { get; private set; } + public TestMsg() { + MsgId = Guid.NewGuid(); + } + } + private void LoadDynamicAssembly() { + var needed = new[] { + "mscorlib", + "netstandard", + "Newtonsoft.Json", + "System", + "System.Core", + "Microsoft.CSharp", + "ReactiveDomain.Messaging", + "ReactiveDomain.Core", + "System.Numerics", + "System.Xml" + }; + + var assemblies = (AppDomain.CurrentDomain + .GetAssemblies() + .Where(reference => needed.Contains(reference.GetName().Name, StringComparer.OrdinalIgnoreCase)) + .Select(reference => reference.Location)).Select(file => (MetadataReference)MetadataReference.CreateFromFile(file)).ToArray(); + + var compilation = CSharpCompilation.Create("TestDynamicAssembly") + .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) + .AddReferences(assemblies) + .AddSyntaxTrees(CSharpSyntaxTree.ParseText( + @"using ReactiveDomain.Messaging; namespace SimpleMsg { public class DynamicMessage : Message { } }")); + + _filePath = AppDomain.CurrentDomain.BaseDirectory + $"\\TestDynamicAssembly{Guid.NewGuid()}.dll"; + + var emitResult = compilation.Emit(_filePath); + if (!emitResult.Success) { + foreach (var diagnostic in emitResult.Diagnostics) { + Console.WriteLine(diagnostic.ToString()); + } + } + + byte[] buffer = File.ReadAllBytes(_filePath); + + AppDomain.CurrentDomain.Load(buffer); + + } + /* Flaky Test //todo: evaluate if we still need this. +#if(NET48) + [Fact] + public void can_dynamically_add_types_without_clearing_handlers() + { + + var bus = InMemoryBus.CreateTest(); + + var fired = false; + bus.Subscribe(new AdHocHandler(m => fired = true)); + + bus.Publish(new TestMsg()); + Assert.True(fired); + + LoadDynamicAssembly(); + var messageType = MessageHierarchy.GetTypeByName("DynamicMessage"); + Assert.Equal("DynamicMessage", messageType[0].Name); + Assert.True(messageType.Count == 1); + + fired = false; + bus.Publish(new TestMsg()); + AssertEx.IsOrBecomesTrue(() => fired); + } +#endif + */ + public void Dispose() { + if (!File.Exists(_filePath)) + return; + try { + File.Delete(_filePath); + } catch { + // ignored + } + } +} +// ReSharper restore InconsistentNaming