diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..3d998f9
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,286 @@
+root = true
+
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = true
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false:error
+dotnet_style_qualification_for_field = false:error
+dotnet_style_qualification_for_method = false:error
+dotnet_style_qualification_for_property = false:error
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:error
+dotnet_style_predefined_type_for_member_access = true:error
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:error
+dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:error
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:error
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:error
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:error
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true:error
+dotnet_style_collection_initializer = true:error
+dotnet_style_explicit_tuple_names = true:error
+dotnet_style_null_propagation = true:error
+dotnet_style_object_initializer = true:error
+dotnet_style_prefer_auto_properties = true:warning
+dotnet_style_prefer_compound_assignment = true:error
+dotnet_style_prefer_conditional_expression_over_assignment = true:error
+dotnet_style_prefer_conditional_expression_over_return = true:error
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:error
+dotnet_style_prefer_inferred_tuple_names = true:error
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error
+
+# Field preferences
+dotnet_style_readonly_field = true:error
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all:error
+
+#### C# Coding Conventions ####
+
+# Namespace preferences
+csharp_style_namespace_declarations=file_scoped:error
+
+# var preferences
+csharp_style_var_elsewhere = false:error
+csharp_style_var_for_built_in_types = false:error
+csharp_style_var_when_type_is_apparent = true:error
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:error
+csharp_style_expression_bodied_constructors = true:error
+csharp_style_expression_bodied_indexers = true:error
+csharp_style_expression_bodied_lambdas = true:error
+csharp_style_expression_bodied_local_functions = true:error
+csharp_style_expression_bodied_methods = true:error
+csharp_style_expression_bodied_operators = true:error
+csharp_style_expression_bodied_properties = true:error
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:error
+csharp_style_pattern_matching_over_is_with_cast_check = true:error
+csharp_style_prefer_switch_expression = true:error
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true:error
+
+# Modifier preferences
+csharp_prefer_static_local_function = true:error
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
+
+# Code-block preferences
+csharp_prefer_braces = true:error
+csharp_prefer_simple_using_statement = true:error
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:error
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_inlined_variable_declaration = true:error
+csharp_style_pattern_local_over_anonymous_function = true:error
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:silent
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:error
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch =true
+csharp_new_line_before_else =true
+csharp_new_line_before_finally =true
+csharp_new_line_before_members_in_anonymous_types = false,
+csharp_new_line_before_members_in_object_initializers = false,
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+# StyleCop.Analyzers
+
+# SA0001: XML comment analysis is disabled due to project configuration
+dotnet_diagnostic.SA0001.severity = none
+
+# SA1101: Prefix local calls with this
+dotnet_diagnostic.SA1101.severity = none
+
+# SA1309: Field names should not begin with underscore
+dotnet_diagnostic.SA1309.severity = none
+
+# SA1413: Use trailing comma in multi-line initializers
+dotnet_diagnostic.SA1413.severity = none
+
+# SA1600: Elements should be documented
+dotnet_diagnostic.SA1600.severity = none
+
+# SA1633: File should have header
+dotnet_diagnostic.SA1633.severity = none
+
+# SA1649: File name should match first type name
+dotnet_diagnostic.SA1649.severity = none
+
+# SonarAnalyzers.CSharp
+
+# S1121: Assignments should not be made from within sub-expressions
+dotnet_diagnostic.S1121.severity = none
+
+# NET.CodeAnalyzers
+
+# CA1000: Do not declare static members on generic types
+dotnet_diagnostic.CA1000.severity = none
+
+# CA1014: Mark assemblies with CLSCompliantAttribute
+dotnet_diagnostic.CA1014.severity = none
+
+# CA1030: Use events where appropriate
+dotnet_diagnostic.CA1030.severity = none
+
+# CA1031: Do not catch general exception types
+dotnet_diagnostic.CA1031.severity = none
+
+# CA1040: Avoid empty interfaces
+dotnet_diagnostic.CA1040.severity = none
+
+# CA1062: Validate arguments of public methods
+dotnet_diagnostic.CA1062.severity = none
+
+# CA1711: Identifiers should not have incorrect suffix
+dotnet_diagnostic.CA1711.severity = none
+
+# CA1716: Identifiers should not match keywords
+dotnet_diagnostic.CA1716.severity = none
+
+# CA1724: Type names should not match namespaces
+dotnet_diagnostic.CA1724.severity = none
+
+# CA2326: Avoid uninstantiated internal classes
+dotnet_diagnostic.CA1812.severity = none
+
+# CA1819: Properties should not return arrays
+dotnet_diagnostic.CA1819.severity = none
+
+# CA1848: Use the LoggerMessage delegates
+dotnet_diagnostic.CA1848.severity = none
+
+# CA2007: Consider calling ConfigureAwait on the awaited task
+dotnet_diagnostic.CA2007.severity = none
+
+# CA2225: Operator overloads have named alternates
+dotnet_diagnostic.CA2225.severity = none
+
+# CA2326: Do not use TypeNameHandling values other than None
+dotnet_diagnostic.CA2326.severity = none
+
+# CA2327: Do not use insecure JsonSerializerSettings
+dotnet_diagnostic.CA2327.severity = none
+
+# Visual Studio.Analyzers
+
+# IDE0046: Convert to conditional expression
+dotnet_diagnostic.IDE0046.severity = none
+
+dotnet_diagnostic.SA1200.severity = none
+
+dotnet_diagnostic.SA1516.severity = none
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index b8f8148..575a862 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -13,6 +13,10 @@
enable
enable
latest
+ true
+ true
+ true
+ latest
1.0.0
@@ -21,4 +25,19 @@
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 5785a4d..34252e9 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,83 @@ dotnet add package UltraSpeedBus.Abstractions
dotnet add package UltraSpeedBus.Extensions.DependencyInjection
```
+# Configure your ``Program``
+```cs
+using UltraSpeedBus.Abstractions;
+using UltraSpeedBus.Abstractions.Contracts;
+using UltraSpeedBus.Abstractions.Mediator;
+using UltraSpeedBus.Extensions.DepedencyInjection;
+using UltraSpeedBus.WebAPI;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+builder.Services.AddUltraSpeedBus(); // Add this method extensions: AddUltraSpeedBus()
+
+// Configure your Command, Query and Event handlers
+builder.Services.AddSingleton, CreateOrderHandler>();
+builder.Services.AddSingleton, GetOrderQueryHandler>();
+builder.Services.AddSingleton, OrderCreatedEventHandler>();
+
+var app = builder.Build();
+
+// more configurations
+
+// Get the mediator instance
+var mediator = app.Services.GetRequiredService();
+
+
+// Register your Commandhandler for CreateOrder record
+mediator.RegisterCommandHandler(
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx)
+);
+
+
+// Register your QueryHandler for GetOrder record
+mediator.RegisterQueryHandler(
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx)
+);
+
+// Register your EventHandler for GetOrder record
+mediator.RegisterEventHandler(
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx)
+);
+
+// Use Minimal APIS
+
+app.MapPost("/orders", async (CreateOrder command, ISend sender) =>
+{
+ var result = await sender.SendAsync(command);
+ return Results.Ok(result);
+});
+
+// GET /orders/{id} -> Send Query
+app.MapGet("/orders/{id:int}", async (int id, ISend sender) =>
+{
+ var result = await sender.SendAsync(new GetOrder(id));
+ if (result is null)
+ return Results.NotFound();
+
+ return Results.Ok(result);
+});
+
+// POST /simulate -> Publish Event directly
+app.MapPost("/simulate", async (IPublish publisher) =>
+{
+ await publisher.PublishAsync(new OrderCreated(999));
+ return Results.Ok("Event Published");
+});
+
+// Example: Dynamic event consumer (runtime registration)
+mediator.ConnectHandlerAsync(async ctx =>
+{
+ Console.WriteLine($"[Dynamic Consumer] Order created with {ctx.Message.OrderId}");
+});
+
+app.Run();
+```
+
## Command handler
```csharp
diff --git a/sample/UltraSpeedBus.WebAPI/CommandHandlers/CreateOrderHandler.cs b/sample/UltraSpeedBus.WebAPI/CommandHandlers/CreateOrderHandler.cs
new file mode 100644
index 0000000..20de683
--- /dev/null
+++ b/sample/UltraSpeedBus.WebAPI/CommandHandlers/CreateOrderHandler.cs
@@ -0,0 +1,26 @@
+using UltraSpeedBus.Abstractions.Contracts;
+
+namespace UltraSpeedBus.WebAPI.CommandHandler;
+
+public sealed record CreateOrder(string product, int quantity);
+public sealed record OrderResult(int orderId);
+public sealed record OrderCreatedEvent(int orderId);
+public sealed record OrderAddedToInventoryEvent(int orderId, int quantity, string sku);
+
+public class CreateOrderHandler : ICommandHandler
+{
+ private readonly IPublish _mediator;
+
+ public CreateOrderHandler(IPublish mediator) => _mediator = mediator;
+
+ public Task Handle(CommandContext request)
+ {
+ // Simula criação de pedido
+ int generatedId = Random.Shared.Next(1000, 9999);
+
+ _mediator.PublishAsync(new OrderCreatedEvent(generatedId));
+ _mediator.PublishAsync(new OrderAddedToInventoryEvent(generatedId, request.Command.quantity, request.Command.product));
+
+ return Task.FromResult(new OrderResult(generatedId));
+ }
+}
diff --git a/sample/UltraSpeedBus.WebAPI/CreateOrderHandler.cs b/sample/UltraSpeedBus.WebAPI/CreateOrderHandler.cs
deleted file mode 100644
index 796dd84..0000000
--- a/sample/UltraSpeedBus.WebAPI/CreateOrderHandler.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using UltraSpeedBus.Abstractions;
-using UltraSpeedBus.Abstractions.Contracts;
-
-
-namespace UltraSpeedBus.WebAPI;
-
-
-#region Command
-public sealed record CreateOrder(string Product, int Quantity);
-public sealed record OrderResult(int OrderId);
-public sealed record OrderCreated(int OrderId);
-
-public class CreateOrderHandler : ICommandHandler
-{
- public Task Handle(CommandContext request)
- {
- // Simula criação de pedido
- int generatedId = Random.Shared.Next(1000, 9999);
-
- return Task.FromResult(new OrderResult(generatedId));
- }
-}
-#endregion
-
-#region Query
-public sealed record GetOrder(int OrderId);
-public sealed record OrderDto(int OrderId, string Description);
-public class GetOrderQueryHandler : IQueryHandler
-{
- public Task Handle(QueryContext context)
- {
- if (context.Query.OrderId == 42)
- {
- return Task.FromResult(new OrderDto(42, "Example Order"));
- }
-
- return Task.FromResult(null);
- }
-}
-#endregion
-
-#region Event
-public class OrderCreatedEventHandler : IEventHandler
-{
- public Task Handle(EventContext context)
- {
- Console.WriteLine($"[Event] Order created → Id = {context.Event.OrderId}");
- return Task.CompletedTask;
- }
-}
-#endregion
\ No newline at end of file
diff --git a/sample/UltraSpeedBus.WebAPI/EventHandler/InventoryEventHandler.cs b/sample/UltraSpeedBus.WebAPI/EventHandler/InventoryEventHandler.cs
new file mode 100644
index 0000000..8739533
--- /dev/null
+++ b/sample/UltraSpeedBus.WebAPI/EventHandler/InventoryEventHandler.cs
@@ -0,0 +1,13 @@
+using UltraSpeedBus.Abstractions.Contracts;
+using UltraSpeedBus.WebAPI.CommandHandler;
+
+namespace UltraSpeedBus.WebAPI.EventHandler;
+
+public class InventoryEventHandler : IEventProcessor
+{
+ public Task Handle(EventContext context)
+ {
+ Console.WriteLine($"[Event] Order added to inventoty → Id = {context.Event.orderId}, Quantity = {context.Event.quantity}, SKU = {context.Event.sku}");
+ return Task.CompletedTask;
+ }
+}
diff --git a/sample/UltraSpeedBus.WebAPI/EventHandler/OrderCreatedEventHandler.cs b/sample/UltraSpeedBus.WebAPI/EventHandler/OrderCreatedEventHandler.cs
new file mode 100644
index 0000000..9e3bdb1
--- /dev/null
+++ b/sample/UltraSpeedBus.WebAPI/EventHandler/OrderCreatedEventHandler.cs
@@ -0,0 +1,13 @@
+using UltraSpeedBus.Abstractions.Contracts;
+using UltraSpeedBus.WebAPI.CommandHandler;
+
+namespace UltraSpeedBus.WebAPI.EventHandler;
+
+public class OrderCreatedEventHandler : IEventProcessor
+{
+ public Task Handle(EventContext context)
+ {
+ Console.WriteLine($"[Event] Order created → Id = {context.Event.orderId}");
+ return Task.CompletedTask;
+ }
+}
diff --git a/sample/UltraSpeedBus.WebAPI/Program.cs b/sample/UltraSpeedBus.WebAPI/Program.cs
index 91cf792..a3b4fa6 100644
--- a/sample/UltraSpeedBus.WebAPI/Program.cs
+++ b/sample/UltraSpeedBus.WebAPI/Program.cs
@@ -1,10 +1,11 @@
-using UltraSpeedBus.Abstractions;
using UltraSpeedBus.Abstractions.Contracts;
using UltraSpeedBus.Abstractions.Mediator;
using UltraSpeedBus.Extensions.DepedencyInjection;
-using UltraSpeedBus.WebAPI;
+using UltraSpeedBus.WebAPI.CommandHandler;
+using UltraSpeedBus.WebAPI.EventHandler;
+using UltraSpeedBus.WebAPI.QueryHandler;
-var builder = WebApplication.CreateBuilder(args);
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
@@ -12,9 +13,10 @@
builder.Services.AddSingleton, CreateOrderHandler>();
builder.Services.AddSingleton, GetOrderQueryHandler>();
-builder.Services.AddSingleton, OrderCreatedEventHandler>();
+builder.Services.AddSingleton, OrderCreatedEventHandler>();
+builder.Services.AddSingleton, InventoryEventHandler>();
-var app = builder.Build();
+WebApplication app = builder.Build();
if (app.Environment.IsDevelopment())
{
@@ -24,32 +26,31 @@
app.UseHttpsRedirection();
-var mediator = app.Services.GetRequiredService();
+IMediator mediator = app.Services.GetRequiredService();
mediator.RegisterCommandHandler(
- (ctx) => app.Services.GetRequiredService>().Handle(ctx)
-);
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx));
mediator.RegisterQueryHandler(
- (ctx) => app.Services.GetRequiredService>().Handle(ctx)
-);
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx));
-mediator.RegisterEventHandler(
- (ctx) => app.Services.GetRequiredService>().Handle(ctx)
-);
+mediator.RegisterEventHandler(
+ (ctx) => app.Services.GetRequiredService>().Handle(ctx));
app.MapPost("/orders", async (CreateOrder command, ISend sender) =>
{
- var result = await sender.SendAsync(command);
+ OrderResult result = await sender.SendAsync(command);
return Results.Ok(result);
});
// GET /orders/{id} -> Send Query
app.MapGet("/orders/{id:int}", async (int id, ISend sender) =>
{
- var result = await sender.SendAsync(new GetOrder(id));
+ OrderDto? result = await sender.SendAsync(new GetOrder(id));
if (result is null)
+ {
return Results.NotFound();
+ }
return Results.Ok(result);
});
@@ -57,14 +58,15 @@
// POST /simulate -> Publish Event directly
app.MapPost("/simulate", async (IPublish publisher) =>
{
- await publisher.PublishAsync(new OrderCreated(999));
+ await publisher.PublishAsync(new OrderCreatedEvent(999));
return Results.Ok("Event Published");
});
// Example: Dynamic event consumer (runtime registration)
-mediator.ConnectHandlerAsync(async ctx =>
-{
- Console.WriteLine($"[Dynamic Consumer] Order created with {ctx.Message.OrderId}");
-});
+mediator.ConnectHandlerAsync(async ctx
+ => Console.WriteLine($"[Dynamic Consumer] Order created with {ctx.Message.orderId}"));
+
+mediator.ConnectHandlerAsync(async ctx
+ => Console.WriteLine($"[Dynamic Consumer] Order added to inventory with {ctx.Message.orderId}, quantity: {ctx.Message.quantity}, sku: {ctx.Message.sku}"));
-app.Run();
+await app.RunAsync();
diff --git a/sample/UltraSpeedBus.WebAPI/QueryHandler/GetOrderQueryHandler.cs b/sample/UltraSpeedBus.WebAPI/QueryHandler/GetOrderQueryHandler.cs
new file mode 100644
index 0000000..5dac645
--- /dev/null
+++ b/sample/UltraSpeedBus.WebAPI/QueryHandler/GetOrderQueryHandler.cs
@@ -0,0 +1,19 @@
+using UltraSpeedBus.Abstractions.Contracts;
+
+namespace UltraSpeedBus.WebAPI.QueryHandler;
+
+public sealed record GetOrder(int orderId);
+public sealed record OrderDto(int orderId, string description);
+
+public class GetOrderQueryHandler : IQueryHandler
+{
+ public Task Handle(QueryContext context)
+ {
+ if (context.Query.orderId == 42)
+ {
+ return Task.FromResult(new OrderDto(42, "Example Order"));
+ }
+
+ return Task.FromResult(null);
+ }
+}
diff --git a/src/UltraSpeedBus.Abstractions/Context/CommandContext.cs b/src/UltraSpeedBus.Abstractions/Context/CommandContext.cs
index 202e311..56aa68f 100644
--- a/src/UltraSpeedBus.Abstractions/Context/CommandContext.cs
+++ b/src/UltraSpeedBus.Abstractions/Context/CommandContext.cs
@@ -1,7 +1,6 @@
namespace UltraSpeedBus.Abstractions.Contracts;
-public class CommandContext
+public class CommandContext(TCommand command)
{
- public TCommand Command { get; }
- public CommandContext(TCommand command) => Command = command;
+ public TCommand Command { get; } = command;
}
diff --git a/src/UltraSpeedBus.Abstractions/Context/ConsumeContext.cs b/src/UltraSpeedBus.Abstractions/Context/ConsumeContext.cs
index be4822b..ae8c5c2 100644
--- a/src/UltraSpeedBus.Abstractions/Context/ConsumeContext.cs
+++ b/src/UltraSpeedBus.Abstractions/Context/ConsumeContext.cs
@@ -1,7 +1,6 @@
namespace UltraSpeedBus.Abstractions.Contracts;
-public class ConsumeContext
+public class ConsumeContext(T message)
{
- public T Message { get; }
- public ConsumeContext(T message) => Message = message;
+ public T Message { get; } = message;
}
diff --git a/src/UltraSpeedBus.Abstractions/Context/EventContext.cs b/src/UltraSpeedBus.Abstractions/Context/EventContext.cs
index 19bf5e4..ff319bf 100644
--- a/src/UltraSpeedBus.Abstractions/Context/EventContext.cs
+++ b/src/UltraSpeedBus.Abstractions/Context/EventContext.cs
@@ -1,7 +1,6 @@
namespace UltraSpeedBus.Abstractions.Contracts;
-public class EventContext
+public class EventContext(TEvent @event)
{
- public TEvent Event { get; }
- public EventContext(TEvent @event) => Event = @event;
+ public TEvent Event { get; } = @event;
}
diff --git a/src/UltraSpeedBus.Abstractions/Context/QueryContext.cs b/src/UltraSpeedBus.Abstractions/Context/QueryContext.cs
index 6228d40..2ea82ba 100644
--- a/src/UltraSpeedBus.Abstractions/Context/QueryContext.cs
+++ b/src/UltraSpeedBus.Abstractions/Context/QueryContext.cs
@@ -1,7 +1,6 @@
namespace UltraSpeedBus.Abstractions.Contracts;
-public class QueryContext
+public class QueryContext(TQuery query)
{
- public TQuery Query { get; }
- public QueryContext(TQuery query) => Query = query;
+ public TQuery Query { get; } = query;
}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/ICommandHandler.cs b/src/UltraSpeedBus.Abstractions/Contracts/ICommandHandler.cs
new file mode 100644
index 0000000..0342786
--- /dev/null
+++ b/src/UltraSpeedBus.Abstractions/Contracts/ICommandHandler.cs
@@ -0,0 +1,6 @@
+namespace UltraSpeedBus.Abstractions.Contracts;
+
+public interface ICommandHandler
+{
+ Task Handle(CommandContext request);
+}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/IConsumerRegister.cs b/src/UltraSpeedBus.Abstractions/Contracts/IConsumerRegister.cs
index 70a85cb..0ac4c07 100644
--- a/src/UltraSpeedBus.Abstractions/Contracts/IConsumerRegister.cs
+++ b/src/UltraSpeedBus.Abstractions/Contracts/IConsumerRegister.cs
@@ -3,6 +3,8 @@ namespace UltraSpeedBus.Abstractions.Contracts;
public interface IConsumerRegister
{
void RegisterCommandHandler(Func, Task> handler);
+
void RegisterQueryHandler(Func, Task> handler);
+
void RegisterEventHandler(Func, Task> handler);
-}
\ No newline at end of file
+}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/IEventProcessor.cs b/src/UltraSpeedBus.Abstractions/Contracts/IEventProcessor.cs
new file mode 100644
index 0000000..76183d0
--- /dev/null
+++ b/src/UltraSpeedBus.Abstractions/Contracts/IEventProcessor.cs
@@ -0,0 +1,6 @@
+namespace UltraSpeedBus.Abstractions.Contracts;
+
+public interface IEventProcessor
+{
+ Task Handle(EventContext request);
+}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/IHandlerHandle.cs b/src/UltraSpeedBus.Abstractions/Contracts/IHandlerHandle.cs
index 94982d5..511bb53 100644
--- a/src/UltraSpeedBus.Abstractions/Contracts/IHandlerHandle.cs
+++ b/src/UltraSpeedBus.Abstractions/Contracts/IHandlerHandle.cs
@@ -1,6 +1,5 @@
namespace UltraSpeedBus.Abstractions.Contracts;
-// TODO implementar IDisposable
public interface IHandlerHandle
{
void Disconnect();
@@ -11,5 +10,5 @@ public interface IDynamicHandler : IHandlerHandle
Type MessageType { get; }
// Handler is typed to generic publishing
- Task Handle(object mesage);
-}
\ No newline at end of file
+ Task Handle(object message);
+}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/IPublish.cs b/src/UltraSpeedBus.Abstractions/Contracts/IPublish.cs
index fe1710d..d138458 100644
--- a/src/UltraSpeedBus.Abstractions/Contracts/IPublish.cs
+++ b/src/UltraSpeedBus.Abstractions/Contracts/IPublish.cs
@@ -2,5 +2,5 @@ namespace UltraSpeedBus.Abstractions.Contracts;
public interface IPublish
{
- Task PublishAsync(TEvent @event);
-}
\ No newline at end of file
+ Task PublishAsync(TEvent message);
+}
diff --git a/src/UltraSpeedBus.Abstractions/Contracts/IQueryHandler.cs b/src/UltraSpeedBus.Abstractions/Contracts/IQueryHandler.cs
new file mode 100644
index 0000000..60baaf2
--- /dev/null
+++ b/src/UltraSpeedBus.Abstractions/Contracts/IQueryHandler.cs
@@ -0,0 +1,6 @@
+namespace UltraSpeedBus.Abstractions.Contracts;
+
+public interface IQueryHandler
+{
+ Task Handle(QueryContext request);
+}
diff --git a/src/UltraSpeedBus.Abstractions/ICommandHandler.cs b/src/UltraSpeedBus.Abstractions/ICommandHandler.cs
deleted file mode 100644
index d734479..0000000
--- a/src/UltraSpeedBus.Abstractions/ICommandHandler.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using UltraSpeedBus.Abstractions.Contracts;
-
-namespace UltraSpeedBus.Abstractions;
-
-public interface ICommandHandler
-{
- Task Handle(CommandContext request);
-}
-
-public interface IQueryHandler
-{
- Task Handle(QueryContext request);
-}
-
-public interface IEventHandler
-{
- Task Handle(EventContext request);
-}
\ No newline at end of file
diff --git a/src/UltraSpeedBus.Abstractions/Mediator/IMediator.cs b/src/UltraSpeedBus.Abstractions/Mediator/IMediator.cs
index 4641035..3d85f4e 100644
--- a/src/UltraSpeedBus.Abstractions/Mediator/IMediator.cs
+++ b/src/UltraSpeedBus.Abstractions/Mediator/IMediator.cs
@@ -8,5 +8,4 @@ public interface IMediator :
IConsumerConnector,
IConsumerRegister
{
-
-}
\ No newline at end of file
+}
diff --git a/src/UltraSpeedBus.Abstractions/Mediator/UltraMediator.cs b/src/UltraSpeedBus.Abstractions/Mediator/UltraMediator.cs
deleted file mode 100644
index 4735e7f..0000000
--- a/src/UltraSpeedBus.Abstractions/Mediator/UltraMediator.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using UltraSpeedBus.Abstractions.Contracts;
-using UltraSpeedBus.Abstractions.Mediator;
-
-namespace UltraSppedBus.Abstractions.Mediator;
-
-public class UltraMediator : IMediator
-{
- private readonly Dictionary>> _commandHandlers = new();
- private readonly Dictionary>> _queryHandlers = new();
- private readonly Dictionary>> _eventHandlers = new();
- private readonly Dictionary> _dynamicHandlers = new();
-
- #region Implement ISend
- // Publisher 1 command x 1 Consumer
- // Publisher 1 query x 1 Consumer
- public Task SendAsync(TRequest request)
- {
- var type = typeof(TRequest);
-
- if (_commandHandlers.TryGetValue(type, out var handler))
- {
- return InvokeHandler(handler, request);
- }
-
- if (_queryHandlers.TryGetValue(type, out var queryHandler))
- {
- return InvokeHandler(queryHandler, request);
- }
-
- throw new InvalidOperationException($"No handler registered for {type.Name}");
- }
- #endregion
-
- #region Implement IPublish
- // Publisher 1 x Many Consumers
- public Task PublishAsync(TEvent @event)
- {
- var type = typeof(TEvent);
- var tasks = new List();
-
- if (_eventHandlers.TryGetValue(type, out var eventHandlers))
- {
- foreach (var handler in eventHandlers)
- tasks.Add(handler(@event));
- }
-
- // You can disable this one
- if (_dynamicHandlers.TryGetValue(type, out var dynamicEventHandlers))
- {
- foreach (var handler in dynamicEventHandlers.OfType>())
- tasks.Add(handler.Handle(@event));
- }
-
- return Task.WhenAll(tasks);
- }
- #endregion
-
- #region Implement IConsumerConnector
- public IHandlerHandle ConnectHandlerAsync(Func, Task> handler)
- {
- var dynamicHandler = new DynamicHandler(this, handler);
-
- lock (_dynamicHandlers)
- {
- if (!_dynamicHandlers.TryGetValue(typeof(TMessage), out var list))
- {
- list = new List();
- _dynamicHandlers.Add(typeof(TMessage), list);
- }
- list.Add(dynamicHandler);
- }
- return dynamicHandler;
- }
- #endregion
-
- #region Implement IConsumerRegister
- public void RegisterCommandHandler(Func, Task> handler)
- {
- _commandHandlers[typeof(TCommand)] = async (object cmd) =>
- {
- var typed = (TCommand)cmd;
- var ctx = new CommandContext(typed);
- var resp = await handler(ctx);
- return resp!;
- };
- }
-
- public void RegisterQueryHandler(Func, Task> handler)
- {
- _queryHandlers[typeof(TQuery)] = async q =>
- {
- var typed = (TQuery)q;
- var ctx = new QueryContext(typed);
- var resp = await handler(ctx);
- return resp!;
- };
- }
-
- public void RegisterEventHandler(Func, Task> handler)
- {
- if (!_eventHandlers.TryGetValue(typeof(TEvent), out var list))
- _eventHandlers[typeof(TEvent)] = list = new List>();
- }
- #endregion
-
- private async Task InvokeHandler(
- Func