-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from Advanced-Systems/new_feature_set
New Feature Set
- Loading branch information
Showing
13 changed files
with
325 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System; | ||
|
||
using Mediator; | ||
|
||
namespace AdvancedSystems.Core.Abstractions; | ||
|
||
/// <summary> | ||
/// Represents a message in the system, which includes an identifier and is used for communication purposes. | ||
/// </summary> | ||
/// <remarks> | ||
/// This interface extends <see cref="INotification"/> to integrate with notification-based systems. | ||
/// Implementations of this interface include a unique identifier to distinguish different messages. | ||
/// </remarks> | ||
public interface IMessage : INotification | ||
{ | ||
/// <summary> | ||
/// Gets the unique identifier of the message. | ||
/// </summary> | ||
/// <value> | ||
/// A <see cref="Guid"/> that uniquely identifies the message. | ||
/// This property is intended to provide a unique reference for each message instance. | ||
/// </value> | ||
Guid Id { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Channels; | ||
using System.Threading.Tasks; | ||
|
||
namespace AdvancedSystems.Core.Abstractions; | ||
|
||
/// <summary> | ||
/// Defines an in-memory message bus for publishing and subscribing to messages of type <see cref="IMessage"/>. | ||
/// </summary> | ||
public interface IMessageBus : IAsyncDisposable | ||
{ | ||
/// <summary> | ||
/// Publishes a message to the message bus. | ||
/// </summary> | ||
/// <typeparam name="T"> | ||
/// The type of the message to subscribe to. Must implement <see cref="IMessage"/>. | ||
/// </typeparam> | ||
/// <param name="message"> | ||
/// The message to be published. | ||
/// </param> | ||
/// <param name="cancellationToken"> | ||
/// Propagates notification that operations should be cancelled. | ||
/// </param> | ||
/// <returns> | ||
/// A <see cref="ValueTask"/> representing the asynchronous operation. | ||
/// </returns> | ||
/// <remarks> | ||
/// This method is used to send messages to the bus. Subscribers will receive these messages asynchronously. | ||
/// </remarks> | ||
ValueTask PublishAsync<T>(T message, CancellationToken cancellationToken = default) where T : class, IMessage; | ||
|
||
/// <summary> | ||
/// Subscribes to messages of type <typeparamref name="T"/> from the message bus. | ||
/// </summary> | ||
/// <typeparam name="T"> | ||
/// The type of the message to subscribe to. Must implement <see cref="IMessage"/>. | ||
/// </typeparam> | ||
/// <param name="cancellationToken"> | ||
/// Propagates notification that operations should be cancelled. | ||
/// </param> | ||
/// <returns> | ||
/// This method is used to receive messages of the specified type from the bus. If no messages | ||
/// of the type are currently available, it will wait until one becomes available. | ||
/// </returns> | ||
/// <exception cref="InvalidCastException"> | ||
/// Thrown when a message retrieved from the channel cannot be cast to the type <typeparamref name="T"/>. | ||
/// </exception> | ||
/// <exception cref="ChannelClosedException"> | ||
/// Thrown when the channel is closed and no more messages are available. This indicates that the channel | ||
/// has been marked as complete and will not accept any more messages. | ||
/// </exception> | ||
ValueTask<T> SubscribeAsync<T>(CancellationToken cancellationToken = default) where T : class, IMessage; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using AdvancedSystems.Core.Abstractions; | ||
using AdvancedSystems.Core.Services; | ||
|
||
namespace AdvancedSystems.Core.Tests.Fixtures; | ||
|
||
public sealed class MessageBusFixture | ||
{ | ||
public MessageBusFixture() | ||
{ | ||
this.MessageBus = new MessageBus(); | ||
} | ||
|
||
#region Properties | ||
|
||
public IMessageBus MessageBus { get; private set; } | ||
|
||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
using AdvancedSystems.Core.Abstractions; | ||
using AdvancedSystems.Core.Tests.Fixtures; | ||
|
||
using Xunit; | ||
|
||
namespace AdvancedSystems.Core.Tests.Services; | ||
|
||
public class MessageBusTests : IClassFixture<MessageBusFixture> | ||
{ | ||
private readonly MessageBusFixture _fixture; | ||
|
||
public MessageBusTests(MessageBusFixture fixture) | ||
{ | ||
this._fixture = fixture; | ||
} | ||
|
||
public record Message(Guid Id) : IMessage; | ||
|
||
public record Passport(Guid Id) : IMessage; | ||
|
||
#region Tests | ||
|
||
[Fact] | ||
public async Task TestPublishSubscribeRoundtrip_HappyPath() | ||
{ | ||
// Arrange | ||
var messageBus = this._fixture.MessageBus; | ||
var expected = new Message(Guid.NewGuid()); | ||
|
||
// Act | ||
await messageBus.PublishAsync(expected); | ||
Message actual = await messageBus.SubscribeAsync<Message>(); | ||
|
||
// Assert | ||
Assert.Equal(expected.Id, actual.Id); | ||
} | ||
|
||
[Fact] | ||
public async Task TestPublishSubscribeRoundtrip_UnhappyPath() | ||
{ | ||
// Arrange | ||
var messageBus = this._fixture.MessageBus; | ||
var expected = new Message(Guid.NewGuid()); | ||
|
||
// Act | ||
await messageBus.PublishAsync(expected); | ||
|
||
async Task SubscribeAsync() | ||
{ | ||
await messageBus.SubscribeAsync<Passport>(); | ||
} | ||
|
||
// Assert | ||
await Assert.ThrowsAsync<InvalidCastException>(SubscribeAsync); | ||
} | ||
|
||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System; | ||
|
||
namespace AdvancedSystems.Core.Common; | ||
|
||
/// <summary> | ||
/// Utility class for capturing additional structured data to enhance the debugging experience. | ||
/// Exception filters run where the exception is thrown, not where the exception is caught, which | ||
/// makes it possible to capture contextual data during logging. | ||
/// </summary> | ||
/// <remarks> | ||
/// The functions defined here don't work well with <c>async</c> code, because <c>async</c> will | ||
/// cause exceptions to be caught and then re-thrown at the point of the <c>await</c>. So, the | ||
/// exception filter runs at the point of the <c>await</c> instead of where the exception was | ||
/// originally thrown. | ||
/// </remarks> | ||
public static class ExceptionFilter | ||
{ | ||
/// <summary> | ||
/// Applies side effects to exception filters when the <c>catch</c> block handles the exception. | ||
/// </summary> | ||
/// <param name="action">The side effect to run in the exception filter.</param> | ||
/// <returns>Returns <c>true</c>.</returns> | ||
public static bool True(Action action) | ||
{ | ||
action(); | ||
return true; | ||
} | ||
|
||
/// <summary> | ||
/// Applies side effects to exception filters when the <c>catch</c> block rethrows the exception. | ||
/// </summary> | ||
/// <param name="action">The side effect to run in the exception filter.</param> | ||
/// <returns>Returns <c>false</c>.</returns> | ||
public static bool False(Action action) | ||
{ | ||
action(); | ||
return false; | ||
} | ||
} |
Oops, something went wrong.