From b1a17be3eb01b3c01e2bd0a5f584127ff40c56cc Mon Sep 17 00:00:00 2001 From: Jason Webb <46631010+JasonMWebb@users.noreply.github.com> Date: Mon, 1 Apr 2024 00:54:21 -0600 Subject: [PATCH] Dev (#118) * EventRouter Updates * Updated dependencies to latest and fixed MassTransit example. * Updated MassTransit test projects. * Promoted EventHandling assembly to RCommon.Core as it is becoming more essential to have loosely coupled events locally in RCommon as well as in dependencies! * Removed deprecated project. * Feature/v2 unit testing (#114) * Changing strategy for entity event tracking. * Removed old icon. Updated EventRouter to allow for parameterized events to be passed in but also stored like a repository. * Updated entity event tracking to enforce better async capabilities. Version bump. * Feature/mediator enhancements (#117) * Removed unneeded samples/files. Renamed existing examples. * Removed DistributedUnitOfWorkBehavior as it is no longer neccesary. The IEntityEventTracker leverages IEventRouter to emit transactional events so we don't need to emit from UoW. * Refactored MediatRNotificationHandler so that events no longer need to implement INotification - only ISerializable which is generic across mulitple types of eventing libraries. * Added ability to send through mediator rather than just publish. * Added Mediator abstraction with MediatR implementation. * Simplified MediatR config. * Added MediatR Request/Notification handling and refactored event handling. * Added Mediator Request with response for MediatR implementation. * Version bump. Co-authored-by: Jason Webb --- .../HR.LeaveManagement.API/Program.cs | 7 +- .../Examples.EventHandling.MediatR/Program.cs | 16 ++-- .../TestEvent.cs | 4 +- .../TestEventHandler.cs | 6 +- .../MyAggregate.cs | 32 -------- .../MyCountEvent.cs | 19 ----- .../Samples.EventSourcing.EventFlow/MyId.cs | 14 ---- .../MyState.cs | 21 ------ .../Program.cs | 2 - .../Samples.EventSourcing.EventFlow.csproj | 18 ----- Examples/Examples.sln | 45 ++++++----- .../ConfigurationContainer.cs | 14 ++++ .../Examples.Mediator.MediatR.csproj | 15 ++++ .../Examples.Mediator.MediatR/Program.cs | 63 ++++++++++++++++ .../TestNotification.cs | 29 ++++++++ .../TestNotificationHandler.cs | 27 +++++++ .../Examples.Mediator.MediatR/TestRequest.cs | 29 ++++++++ .../TestRequestHandler.cs | 29 ++++++++ .../TestRequestHandlerWithResponse.cs | 26 +++++++ .../Examples.Mediator.MediatR/TestResponse.cs | 18 +++++ .../ConfigurationContainer.cs | 0 .../Examples.Messaging.MassTransit.csproj | 0 .../Program.cs | 0 .../TestEvent.cs | 0 .../TestEventHandler.cs | 0 .../Worker.cs | 0 .../ConfigurationContainer.cs | 0 .../Examples.Messaging.Wolverine.csproj | 0 .../Program.cs | 0 .../TestEvent.cs | 0 .../TestEventHandler.cs | 0 .../CqrsBuilder.cs | 2 +- .../RCommon.ApplicationServices.csproj | 2 +- .../RCommon.Authorization.Web.csproj | 2 +- .../EventHandlingBuilderExtensions.cs | 8 +- .../EventHandling/Producers/IEventProducer.cs | 3 +- .../EventHandling/Producers/IEventRouter.cs | 4 +- .../InMemoryTransactionalEventRouter.cs | 6 +- .../EventHandling/Subscribers/ISubscriber.cs | 4 +- Src/RCommon.Core/RCommon.Core.csproj | 2 +- Src/RCommon.Dapper/RCommon.Dapper.csproj | 2 +- Src/RCommon.EfCore/RCommon.EFCore.csproj | 2 +- Src/RCommon.EfCore/RCommonDbContext.cs | 8 +- Src/RCommon.Emailing/RCommon.Emailing.csproj | 2 +- Src/RCommon.Entities/IEntityEventTracker.cs | 2 +- .../InMemoryEntityEventTracker.cs | 6 +- Src/RCommon.Entities/RCommon.Entities.csproj | 2 +- Src/RCommon.Linq2Db/RCommon.Linq2Db.csproj | 2 +- Src/RCommon.Linq2Db/RCommonDataConnection.cs | 8 +- .../RCommon.MassTransit.csproj | 2 +- .../IAppNotificationHandler.cs | 18 ----- Src/RCommon.Mediator/IAppRequestHandler.cs | 13 ---- Src/RCommon.Mediator/IMediatorAdapter.cs | 18 +++++ Src/RCommon.Mediator/IMediatorBuilder.cs | 4 +- Src/RCommon.Mediator/IMediatorService.cs | 13 ++-- .../MediatorBuilderExtensions.cs | 20 +++-- Src/RCommon.Mediator/MediatorService.cs | 35 +++++++++ .../PublishWithMediatorEventProducer.cs | 26 ------- .../SendWithMediatorEventProducer.cs | 26 ------- Src/RCommon.Mediator/RCommon.Mediator.csproj | 2 +- .../{ => Subscribers}/IAppNotification.cs | 2 +- .../{ => Subscribers}/IAppRequest.cs | 8 +- .../Subscribers/IAppRequestHandler.cs | 18 +++++ .../DistributedUnitOfWorkBehavior.cs | 62 ---------------- .../Behaviors/ValidatorBehavior.cs | 1 - Src/RCommon.Mediatr/IMediatRBuilder.cs | 10 +-- .../IMediatREventHandlingBuilder.cs | 10 +++ Src/RCommon.Mediatr/INotificationHandler.cs | 9 --- Src/RCommon.Mediatr/MediatRAdapter.cs | 49 ++++++++++++ Src/RCommon.Mediatr/MediatRBuilder.cs | 36 +++++++-- .../MediatRBuilderExtensions.cs | 51 +++++++++---- .../MediatREventHandlingBuilder.cs | 24 +++--- .../MediatREventHandlingBuilderExtensions.cs | 55 +++++++++++--- .../MediatRNotificationHandler.cs | 31 -------- Src/RCommon.Mediatr/MediatRRequest.cs | 20 ----- Src/RCommon.Mediatr/MediatRRequestHandler.cs | 27 ------- Src/RCommon.Mediatr/MediatRService.cs | 31 -------- .../PublishWithMediatREventProducer.cs | 30 ++++++++ .../Producers/SendWithMediatREventProducer.cs | 30 ++++++++ Src/RCommon.Mediatr/RCommon.MediatR.csproj | 4 +- .../Subscribers/IMediatRNotification.cs | 15 ++++ .../Subscribers/IMediatRRequest.cs | 20 +++++ .../Subscribers/MediatREventHandler.cs | 38 ++++++++++ .../{ => Subscribers}/MediatRNotification.cs | 6 +- .../Subscribers/MediatRNotificationHandler.cs | 39 ++++++++++ .../Subscribers/MediatRRequest.cs | 32 ++++++++ .../Subscribers/MediatRRequestHandler.cs | 63 ++++++++++++++++ Src/RCommon.Models/RCommon.Models.csproj | 2 +- .../RCommon.Persistence.csproj | 2 +- Src/RCommon.Persistence/Sql/RDbConnection.cs | 14 +++- .../Authorization/AuthorizationException.cs | 9 --- Src/RCommon.Security/RCommon.Security.csproj | 2 +- Src/RCommon.SendGrid/RCommon.SendGrid.csproj | 2 +- Src/RCommon.Web/RCommon.Web.csproj | 2 +- .../RCommon.Wolverine.csproj | 2 +- .../DistributedUnitOfWorkBehaviorTests.cs | 67 ----------------- .../Behaviors/LoggingBehaviorTests.cs | 59 --------------- .../Behaviors/UnitOfWorkBehaviorTests.cs | 64 ---------------- .../Behaviors/ValidatorBehaviorTests.cs | 63 ---------------- .../MediatrConfigurationTests.cs | 70 ------------------ .../MediatrServiceTests.cs | 74 ------------------- 101 files changed, 901 insertions(+), 930 deletions(-) delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyAggregate.cs delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyCountEvent.cs delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyId.cs delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyState.cs delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/Program.cs delete mode 100644 Examples/EventSourcing/Samples.EventSourcing.EventFlow/Samples.EventSourcing.EventFlow.csproj create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/ConfigurationContainer.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/Examples.Mediator.MediatR.csproj create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/Program.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestNotification.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestNotificationHandler.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestRequest.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandler.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandlerWithResponse.cs create mode 100644 Examples/Mediator/Examples.Mediator.MediatR/TestResponse.cs rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/ConfigurationContainer.cs (100%) rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/Examples.Messaging.MassTransit.csproj (100%) rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/Program.cs (100%) rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/TestEvent.cs (100%) rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/TestEventHandler.cs (100%) rename Examples/Messaging/{Samples.Messaging.MassTransitRabbitMq => Examples.Messaging.MassTransit}/Worker.cs (100%) rename Examples/Messaging/{Samples.Messaging.WolverineRabbitMq => Examples.Messaging.Wolverine}/ConfigurationContainer.cs (100%) rename Examples/Messaging/{Samples.Messaging.WolverineRabbitMq => Examples.Messaging.Wolverine}/Examples.Messaging.Wolverine.csproj (100%) rename Examples/Messaging/{Samples.Messaging.WolverineRabbitMq => Examples.Messaging.Wolverine}/Program.cs (100%) rename Examples/Messaging/{Samples.Messaging.WolverineRabbitMq => Examples.Messaging.Wolverine}/TestEvent.cs (100%) rename Examples/Messaging/{Samples.Messaging.WolverineRabbitMq => Examples.Messaging.Wolverine}/TestEventHandler.cs (100%) delete mode 100644 Src/RCommon.Mediator/IAppNotificationHandler.cs delete mode 100644 Src/RCommon.Mediator/IAppRequestHandler.cs create mode 100644 Src/RCommon.Mediator/IMediatorAdapter.cs create mode 100644 Src/RCommon.Mediator/MediatorService.cs delete mode 100644 Src/RCommon.Mediator/Producers/PublishWithMediatorEventProducer.cs delete mode 100644 Src/RCommon.Mediator/Producers/SendWithMediatorEventProducer.cs rename Src/RCommon.Mediator/{ => Subscribers}/IAppNotification.cs (81%) rename Src/RCommon.Mediator/{ => Subscribers}/IAppRequest.cs (63%) create mode 100644 Src/RCommon.Mediator/Subscribers/IAppRequestHandler.cs delete mode 100644 Src/RCommon.Mediatr/Behaviors/DistributedUnitOfWorkBehavior.cs create mode 100644 Src/RCommon.Mediatr/IMediatREventHandlingBuilder.cs delete mode 100644 Src/RCommon.Mediatr/INotificationHandler.cs create mode 100644 Src/RCommon.Mediatr/MediatRAdapter.cs delete mode 100644 Src/RCommon.Mediatr/MediatRNotificationHandler.cs delete mode 100644 Src/RCommon.Mediatr/MediatRRequest.cs delete mode 100644 Src/RCommon.Mediatr/MediatRRequestHandler.cs delete mode 100644 Src/RCommon.Mediatr/MediatRService.cs create mode 100644 Src/RCommon.Mediatr/Producers/PublishWithMediatREventProducer.cs create mode 100644 Src/RCommon.Mediatr/Producers/SendWithMediatREventProducer.cs create mode 100644 Src/RCommon.Mediatr/Subscribers/IMediatRNotification.cs create mode 100644 Src/RCommon.Mediatr/Subscribers/IMediatRRequest.cs create mode 100644 Src/RCommon.Mediatr/Subscribers/MediatREventHandler.cs rename Src/RCommon.Mediatr/{ => Subscribers}/MediatRNotification.cs (62%) create mode 100644 Src/RCommon.Mediatr/Subscribers/MediatRNotificationHandler.cs create mode 100644 Src/RCommon.Mediatr/Subscribers/MediatRRequest.cs create mode 100644 Src/RCommon.Mediatr/Subscribers/MediatRRequestHandler.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/Behaviors/DistributedUnitOfWorkBehaviorTests.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/Behaviors/LoggingBehaviorTests.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/Behaviors/UnitOfWorkBehaviorTests.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/Behaviors/ValidatorBehaviorTests.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/MediatrConfigurationTests.cs delete mode 100644 Tests/RCommon.Mediator.MediatR.Tests/MediatrServiceTests.cs diff --git a/Examples/CleanWithCQRS/HR.LeaveManagement.API/Program.cs b/Examples/CleanWithCQRS/HR.LeaveManagement.API/Program.cs index c234bfdd..5b06ffb8 100644 --- a/Examples/CleanWithCQRS/HR.LeaveManagement.API/Program.cs +++ b/Examples/CleanWithCQRS/HR.LeaveManagement.API/Program.cs @@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore; using System.Transactions; using RCommon.Persistence.Transactions; +using RCommon.Mediator.MediatR; var builder = WebApplication.CreateBuilder(args); @@ -30,7 +31,11 @@ }) .WithDateTimeSystem(dateTime => dateTime.Kind = DateTimeKind.Utc) .WithSequentialGuidGenerator(guid => guid.DefaultSequentialGuidType = SequentialGuidType.SequentialAsString) - .AddUnitOfWorkToMediatorPipeline() + .WithMediator(mediator => + { + mediator.AddLoggingToRequestPipeline(); + mediator.AddUnitOfWorkToRequestPipeline(); + }) .WithPersistence(ef => // Repository/ORM configuration. We could easily swap out to NHibernate without impact to domain service up through the stack { // Add all the DbContexts here diff --git a/Examples/EventHandling/Examples.EventHandling.MediatR/Program.cs b/Examples/EventHandling/Examples.EventHandling.MediatR/Program.cs index 92b490cf..1c94089e 100644 --- a/Examples/EventHandling/Examples.EventHandling.MediatR/Program.cs +++ b/Examples/EventHandling/Examples.EventHandling.MediatR/Program.cs @@ -6,13 +6,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using RCommon; -using RCommon.EventHandling; using RCommon.EventHandling.Producers; -using RCommon.Mediator; -using RCommon.Mediator.MediatR; -using RCommon.Mediator.Producers; using RCommon.MediatR; +using RCommon.MediatR.Producers; using System.Diagnostics; +using System.Reflection; +using static System.Net.Mime.MediaTypeNames; try { @@ -27,16 +26,13 @@ { // Configure RCommon services.AddRCommon() - .WithEventHandling(eventHandling => + .WithEventHandling(eventHandling => { - eventHandling.AddProducer(); + eventHandling.AddProducer(); + eventHandling.AddSubscriber(); - //services.AddTransient, TestEventHandler>(); }); - Console.WriteLine($"Total Services Registered:"); - Console.WriteLine(services.GenerateServiceDescriptorsString()); - }).Build(); Console.WriteLine("Example Starting"); diff --git a/Examples/EventHandling/Examples.EventHandling.MediatR/TestEvent.cs b/Examples/EventHandling/Examples.EventHandling.MediatR/TestEvent.cs index 14ae956e..bbcb9746 100644 --- a/Examples/EventHandling/Examples.EventHandling.MediatR/TestEvent.cs +++ b/Examples/EventHandling/Examples.EventHandling.MediatR/TestEvent.cs @@ -1,5 +1,7 @@ -using RCommon.EventHandling; +using MediatR; +using RCommon.EventHandling; using RCommon.Mediator; +using RCommon.Mediator.Subscribers; using System; using System.Collections.Generic; using System.Linq; diff --git a/Examples/EventHandling/Examples.EventHandling.MediatR/TestEventHandler.cs b/Examples/EventHandling/Examples.EventHandling.MediatR/TestEventHandler.cs index 74de5fd0..17d1f8a7 100644 --- a/Examples/EventHandling/Examples.EventHandling.MediatR/TestEventHandler.cs +++ b/Examples/EventHandling/Examples.EventHandling.MediatR/TestEventHandler.cs @@ -1,4 +1,5 @@ using MediatR; +using RCommon; using RCommon.EventHandling.Subscribers; using RCommon.Mediator; using System; @@ -14,13 +15,12 @@ public class TestEventHandler : ISubscriber { public TestEventHandler() { - + } - public async Task HandleAsync(TestEvent notification, CancellationToken cancellationToken = default) { - Console.WriteLine("I just handled this event {0}", new object[] { notification.ToString() }); + Console.WriteLine("{0} just handled this event {1}", new object[] { this.GetGenericTypeName(), notification }); await Task.CompletedTask; } } diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyAggregate.cs b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyAggregate.cs deleted file mode 100644 index 7a56b09f..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyAggregate.cs +++ /dev/null @@ -1,32 +0,0 @@ -using EventFlow.Aggregates; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Samples.EventSourcing.EventFlow -{ - public class MyAggregate : AggregateRoot, RCommon.Entities.Domain.IAggregateRoot - { - public MyState State { get; private set; } - - public MyAggregate(MyId id) : base(id) - { - State = new MyState(); - Register(State); - } - - public void Count(int count) - { - Emit(new MyCountEvent(count)); - } - - public void AddDomainEvent(RCommon.Entities.Domain.IDomainEvent eventItem) - { - throw new NotImplementedException(); - } - - - } -} diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyCountEvent.cs b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyCountEvent.cs deleted file mode 100644 index 3da04391..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyCountEvent.cs +++ /dev/null @@ -1,19 +0,0 @@ -using EventFlow.Aggregates; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Samples.EventSourcing.EventFlow -{ - public class MyCountEvent : IAggregateEvent, RCommon.Entities.Domain.IDomainEvent - { - public int Count { get; private set; } - - public MyCountEvent(int count) - { - Count = count; - } - } -} diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyId.cs b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyId.cs deleted file mode 100644 index ae84fbd6..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyId.cs +++ /dev/null @@ -1,14 +0,0 @@ -using EventFlow.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Samples.EventSourcing.EventFlow -{ - public class MyId : Identity - { - public MyId(string value) : base(value) { } - } -} diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyState.cs b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyState.cs deleted file mode 100644 index 5454aaac..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/MyState.cs +++ /dev/null @@ -1,21 +0,0 @@ -using EventFlow.Aggregates; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Samples.EventSourcing.EventFlow -{ - public class MyState : IEventApplier - { - public int Count { get; private set; } - - public bool Apply(MyAggregate aggregate, IAggregateEvent aggregateEvent) - { - var myCountEvent = (MyCountEvent)aggregateEvent; - Count += myCountEvent.Count; - return true; - } - } -} diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Program.cs b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Program.cs deleted file mode 100644 index 3751555c..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Program.cs +++ /dev/null @@ -1,2 +0,0 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); diff --git a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Samples.EventSourcing.EventFlow.csproj b/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Samples.EventSourcing.EventFlow.csproj deleted file mode 100644 index 2678216b..00000000 --- a/Examples/EventSourcing/Samples.EventSourcing.EventFlow/Samples.EventSourcing.EventFlow.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - net7.0 - enable - enable - - - - - - - - - - - diff --git a/Examples/Examples.sln b/Examples/Examples.sln index f93bdbd4..c8e86d75 100644 --- a/Examples/Examples.sln +++ b/Examples/Examples.sln @@ -89,10 +89,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RCommon.Mediator.MediatR.Te EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Messaging", "Messaging", "{35AE0870-0A6D-4F27-B534-B8DCDFD11A36}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Messaging.MassTransit", "Messaging\Samples.Messaging.MassTransitRabbitMq\Examples.Messaging.MassTransit.csproj", "{FC74E2FD-5B2D-4301-ABB7-838F458ED50D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Messaging.Wolverine", "Messaging\Samples.Messaging.WolverineRabbitMq\Examples.Messaging.Wolverine.csproj", "{B792333E-245B-48F0-A88E-F36EEF1F7C11}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{3199F749-0082-41D0-91D3-ECED117F8B08}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RCommon.DotNet6.Tests", "..\Tests\RCommon.DotNet6.Tests\RCommon.DotNet6.Tests.csproj", "{B93C2373-7ADD-4D1F-B8CB-8FF32EAF364E}" @@ -109,12 +105,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventHandling.Medi EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CQRS", "CQRS", "{783F8A99-F164-42E3-BD7C-09D432D02DEE}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Experimental", "Experimental", "{6509FEEC-F46C-4B03-82D4-8F2D78896160}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventHandling.InMemoryEventBus", "EventHandling\Examples.EventHandling.InMemoryEventBus\Examples.EventHandling.InMemoryEventBus.csproj", "{86CE6DBE-418E-440B-9C27-58B00AFB2FCA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.ApplicationServices.CQRS", "ApplicationServices\Examples.ApplicationServices.CQRS\Examples.ApplicationServices.CQRS.csproj", "{CEAA39C2-249C-44D0-94CF-8342CB35811D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Messaging.MassTransit", "Messaging\Examples.Messaging.MassTransit\Examples.Messaging.MassTransit.csproj", "{A7C5D513-08D7-4BBF-9CB9-307EE91DA81D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Messaging.Wolverine", "Messaging\Examples.Messaging.Wolverine\Examples.Messaging.Wolverine.csproj", "{06FE76EC-C7D1-4C46-8047-22D58C8437A2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Mediator.MediatR", "Mediator\Examples.Mediator.MediatR\Examples.Mediator.MediatR.csproj", "{05B6EF05-8053-45D1-8649-1779B0D7D6C7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mediator", "Mediator", "{9085B4F5-E26A-471D-B25D-5D69B0337B02}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -261,14 +263,6 @@ Global {38508541-4429-4A30-9D84-B151250E08B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {38508541-4429-4A30-9D84-B151250E08B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {38508541-4429-4A30-9D84-B151250E08B8}.Release|Any CPU.Build.0 = Release|Any CPU - {FC74E2FD-5B2D-4301-ABB7-838F458ED50D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC74E2FD-5B2D-4301-ABB7-838F458ED50D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC74E2FD-5B2D-4301-ABB7-838F458ED50D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC74E2FD-5B2D-4301-ABB7-838F458ED50D}.Release|Any CPU.Build.0 = Release|Any CPU - {B792333E-245B-48F0-A88E-F36EEF1F7C11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B792333E-245B-48F0-A88E-F36EEF1F7C11}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B792333E-245B-48F0-A88E-F36EEF1F7C11}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B792333E-245B-48F0-A88E-F36EEF1F7C11}.Release|Any CPU.Build.0 = Release|Any CPU {B93C2373-7ADD-4D1F-B8CB-8FF32EAF364E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B93C2373-7ADD-4D1F-B8CB-8FF32EAF364E}.Debug|Any CPU.Build.0 = Debug|Any CPU {B93C2373-7ADD-4D1F-B8CB-8FF32EAF364E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -297,6 +291,18 @@ Global {CEAA39C2-249C-44D0-94CF-8342CB35811D}.Debug|Any CPU.Build.0 = Debug|Any CPU {CEAA39C2-249C-44D0-94CF-8342CB35811D}.Release|Any CPU.ActiveCfg = Release|Any CPU {CEAA39C2-249C-44D0-94CF-8342CB35811D}.Release|Any CPU.Build.0 = Release|Any CPU + {A7C5D513-08D7-4BBF-9CB9-307EE91DA81D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7C5D513-08D7-4BBF-9CB9-307EE91DA81D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7C5D513-08D7-4BBF-9CB9-307EE91DA81D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7C5D513-08D7-4BBF-9CB9-307EE91DA81D}.Release|Any CPU.Build.0 = Release|Any CPU + {06FE76EC-C7D1-4C46-8047-22D58C8437A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06FE76EC-C7D1-4C46-8047-22D58C8437A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06FE76EC-C7D1-4C46-8047-22D58C8437A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06FE76EC-C7D1-4C46-8047-22D58C8437A2}.Release|Any CPU.Build.0 = Release|Any CPU + {05B6EF05-8053-45D1-8649-1779B0D7D6C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05B6EF05-8053-45D1-8649-1779B0D7D6C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05B6EF05-8053-45D1-8649-1779B0D7D6C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05B6EF05-8053-45D1-8649-1779B0D7D6C7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -329,22 +335,23 @@ Global {F026BAB4-FBBE-4AF5-8187-AA3ADF540053} = {0AF37317-F10E-47E8-A4C8-9EA886E00E40} {D02ADFB9-822C-47BD-B5E9-4469F57CD8AB} = {F026BAB4-FBBE-4AF5-8187-AA3ADF540053} {52003D9E-B698-4E48-BD97-3702DD8F91A9} = {F026BAB4-FBBE-4AF5-8187-AA3ADF540053} - {0987AF3F-6EFC-4AE6-9007-DE9533934D82} = {6509FEEC-F46C-4B03-82D4-8F2D78896160} - {0CE7EC46-274F-4D46-A344-1F92E1D23923} = {6509FEEC-F46C-4B03-82D4-8F2D78896160} + {0987AF3F-6EFC-4AE6-9007-DE9533934D82} = {3199F749-0082-41D0-91D3-ECED117F8B08} {86B19A1B-17F9-410F-8B97-74FE3EE7A4BE} = {0AF37317-F10E-47E8-A4C8-9EA886E00E40} {38508541-4429-4A30-9D84-B151250E08B8} = {86B19A1B-17F9-410F-8B97-74FE3EE7A4BE} {35AE0870-0A6D-4F27-B534-B8DCDFD11A36} = {3234C3BB-1632-4684-838E-9D6D382D4D4D} - {FC74E2FD-5B2D-4301-ABB7-838F458ED50D} = {35AE0870-0A6D-4F27-B534-B8DCDFD11A36} - {B792333E-245B-48F0-A88E-F36EEF1F7C11} = {35AE0870-0A6D-4F27-B534-B8DCDFD11A36} {B93C2373-7ADD-4D1F-B8CB-8FF32EAF364E} = {788A01F9-0510-441A-B05B-0CDA0EE87507} {CABBB120-77E7-4C1D-B706-D934BE1C035C} = {788A01F9-0510-441A-B05B-0CDA0EE87507} {75F1593B-B15D-41E5-B404-020B35A3F691} = {788A01F9-0510-441A-B05B-0CDA0EE87507} {90B4A098-01AB-4B35-987E-838F2241DA17} = {3199F749-0082-41D0-91D3-ECED117F8B08} {FCC70943-06B2-4743-A99D-82F5122297F3} = {3234C3BB-1632-4684-838E-9D6D382D4D4D} - {213F2EFE-F1DF-471C-A518-94D107DD543F} = {6509FEEC-F46C-4B03-82D4-8F2D78896160} + {213F2EFE-F1DF-471C-A518-94D107DD543F} = {FCC70943-06B2-4743-A99D-82F5122297F3} {783F8A99-F164-42E3-BD7C-09D432D02DEE} = {3234C3BB-1632-4684-838E-9D6D382D4D4D} {86CE6DBE-418E-440B-9C27-58B00AFB2FCA} = {FCC70943-06B2-4743-A99D-82F5122297F3} {CEAA39C2-249C-44D0-94CF-8342CB35811D} = {783F8A99-F164-42E3-BD7C-09D432D02DEE} + {A7C5D513-08D7-4BBF-9CB9-307EE91DA81D} = {35AE0870-0A6D-4F27-B534-B8DCDFD11A36} + {06FE76EC-C7D1-4C46-8047-22D58C8437A2} = {35AE0870-0A6D-4F27-B534-B8DCDFD11A36} + {05B6EF05-8053-45D1-8649-1779B0D7D6C7} = {9085B4F5-E26A-471D-B25D-5D69B0337B02} + {9085B4F5-E26A-471D-B25D-5D69B0337B02} = {3234C3BB-1632-4684-838E-9D6D382D4D4D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0B0CD26D-8067-4667-863E-6B0EE7EDAA42} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/ConfigurationContainer.cs b/Examples/Mediator/Examples.Mediator.MediatR/ConfigurationContainer.cs new file mode 100644 index 00000000..d01c46ed --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/ConfigurationContainer.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + internal static class ConfigurationContainer + { + public static IConfiguration Configuration { get; set; } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/Examples.Mediator.MediatR.csproj b/Examples/Mediator/Examples.Mediator.MediatR/Examples.Mediator.MediatR.csproj new file mode 100644 index 00000000..a72539ad --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/Examples.Mediator.MediatR.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + diff --git a/Examples/Mediator/Examples.Mediator.MediatR/Program.cs b/Examples/Mediator/Examples.Mediator.MediatR/Program.cs new file mode 100644 index 00000000..4dd28d04 --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/Program.cs @@ -0,0 +1,63 @@ + +using Examples.Mediator.MediatR; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using RCommon; +using RCommon.EventHandling.Producers; +using RCommon.Mediator; +using RCommon.Mediator.MediatR; +using RCommon.MediatR; +using RCommon.MediatR.Producers; +using System.Diagnostics; +using System.Reflection; +using static System.Net.Mime.MediaTypeNames; + +try +{ + var host = Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((context, builder) => + { + + ConfigurationContainer.Configuration = builder + .Build(); + }) + .ConfigureServices(services => + { + // Configure RCommon + services.AddRCommon() + .WithMediator(mediator => + { + mediator.AddNotification(); + mediator.AddRequest(); + mediator.AddRequest(); + + // Additional configurations can be set like below + mediator.Configure(config => + { + config.RegisterServicesFromAssemblies((typeof(Program).GetTypeInfo().Assembly)); + }); + }); + + }).Build(); + + Console.WriteLine("Example Starting"); + var mediatorService = host.Services.GetService(); + var notification = new TestNotification(DateTime.Now, Guid.NewGuid()); + var request = new TestRequest(DateTime.Now, Guid.NewGuid()); + + await mediatorService.Publish(notification); // For multiple handlers + await mediatorService.Send(request); // For a single endpoint + + var response = await mediatorService.Send(request); // For a single endpoint with a response + Console.WriteLine("Response: {0}", response.Message); + + Console.WriteLine("Example Complete"); + Console.ReadLine(); +} +catch (Exception ex) +{ + Console.WriteLine(ex.ToString()); + +} + diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestNotification.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestNotification.cs new file mode 100644 index 00000000..99257496 --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestNotification.cs @@ -0,0 +1,29 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.Mediator; +using RCommon.Mediator.Subscribers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestNotification : IAppNotification + { + public TestNotification(DateTime dateTime, Guid guid) + { + DateTime = dateTime; + Guid = guid; + } + + public TestNotification() + { + + } + + public DateTime DateTime { get; } + public Guid Guid { get; } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestNotificationHandler.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestNotificationHandler.cs new file mode 100644 index 00000000..2d3f9ba6 --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestNotificationHandler.cs @@ -0,0 +1,27 @@ +using MediatR; +using RCommon; +using RCommon.EventHandling.Subscribers; +using RCommon.Mediator; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestNotificationHandler : ISubscriber + { + public TestNotificationHandler() + { + + } + + public async Task HandleAsync(TestNotification @event, CancellationToken cancellationToken = default) + { + Console.WriteLine("{0} just handled this notification {1}", new object[] { this.GetGenericTypeName(), @event }); + await Task.CompletedTask; + } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestRequest.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestRequest.cs new file mode 100644 index 00000000..4db2f2be --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestRequest.cs @@ -0,0 +1,29 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.Mediator; +using RCommon.Mediator.Subscribers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestRequest : IAppRequest + { + public TestRequest(DateTime dateTime, Guid guid) + { + DateTime = dateTime; + Guid = guid; + } + + public TestRequest() + { + + } + + public DateTime DateTime { get; } + public Guid Guid { get; } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandler.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandler.cs new file mode 100644 index 00000000..1c8ae7ed --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandler.cs @@ -0,0 +1,29 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using RCommon; +using RCommon.EventHandling.Subscribers; +using RCommon.Mediator; +using RCommon.Mediator.Subscribers; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestRequestHandler : IAppRequestHandler + { + public TestRequestHandler() + { + + } + + public async Task HandleAsync(TestRequest request, CancellationToken cancellationToken = default) + { + Console.WriteLine("{0} just handled this request {1}", new object[] { this.GetGenericTypeName(), request }); + await Task.CompletedTask; + } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandlerWithResponse.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandlerWithResponse.cs new file mode 100644 index 00000000..dfb51ec7 --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestRequestHandlerWithResponse.cs @@ -0,0 +1,26 @@ +using RCommon; +using RCommon.Mediator.Subscribers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestRequestHandlerWithResponse : IAppRequestHandler + { + public TestRequestHandlerWithResponse() + { + + } + + public async Task HandleAsync(TestRequest request, CancellationToken cancellationToken) + { + Console.WriteLine("{0} just handled this request {1}", new object[] { this.GetGenericTypeName(), request }); + + var response = new TestResponse("Test Response Worked"); + return await Task.FromResult(response); + } + } +} diff --git a/Examples/Mediator/Examples.Mediator.MediatR/TestResponse.cs b/Examples/Mediator/Examples.Mediator.MediatR/TestResponse.cs new file mode 100644 index 00000000..f088d976 --- /dev/null +++ b/Examples/Mediator/Examples.Mediator.MediatR/TestResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Examples.Mediator.MediatR +{ + public class TestResponse + { + public TestResponse(string message) + { + Message = message; + } + + public string Message { get; } + } +} diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/ConfigurationContainer.cs b/Examples/Messaging/Examples.Messaging.MassTransit/ConfigurationContainer.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/ConfigurationContainer.cs rename to Examples/Messaging/Examples.Messaging.MassTransit/ConfigurationContainer.cs diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Examples.Messaging.MassTransit.csproj b/Examples/Messaging/Examples.Messaging.MassTransit/Examples.Messaging.MassTransit.csproj similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Examples.Messaging.MassTransit.csproj rename to Examples/Messaging/Examples.Messaging.MassTransit/Examples.Messaging.MassTransit.csproj diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Program.cs b/Examples/Messaging/Examples.Messaging.MassTransit/Program.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Program.cs rename to Examples/Messaging/Examples.Messaging.MassTransit/Program.cs diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/TestEvent.cs b/Examples/Messaging/Examples.Messaging.MassTransit/TestEvent.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/TestEvent.cs rename to Examples/Messaging/Examples.Messaging.MassTransit/TestEvent.cs diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/TestEventHandler.cs b/Examples/Messaging/Examples.Messaging.MassTransit/TestEventHandler.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/TestEventHandler.cs rename to Examples/Messaging/Examples.Messaging.MassTransit/TestEventHandler.cs diff --git a/Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Worker.cs b/Examples/Messaging/Examples.Messaging.MassTransit/Worker.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.MassTransitRabbitMq/Worker.cs rename to Examples/Messaging/Examples.Messaging.MassTransit/Worker.cs diff --git a/Examples/Messaging/Samples.Messaging.WolverineRabbitMq/ConfigurationContainer.cs b/Examples/Messaging/Examples.Messaging.Wolverine/ConfigurationContainer.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.WolverineRabbitMq/ConfigurationContainer.cs rename to Examples/Messaging/Examples.Messaging.Wolverine/ConfigurationContainer.cs diff --git a/Examples/Messaging/Samples.Messaging.WolverineRabbitMq/Examples.Messaging.Wolverine.csproj b/Examples/Messaging/Examples.Messaging.Wolverine/Examples.Messaging.Wolverine.csproj similarity index 100% rename from Examples/Messaging/Samples.Messaging.WolverineRabbitMq/Examples.Messaging.Wolverine.csproj rename to Examples/Messaging/Examples.Messaging.Wolverine/Examples.Messaging.Wolverine.csproj diff --git a/Examples/Messaging/Samples.Messaging.WolverineRabbitMq/Program.cs b/Examples/Messaging/Examples.Messaging.Wolverine/Program.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.WolverineRabbitMq/Program.cs rename to Examples/Messaging/Examples.Messaging.Wolverine/Program.cs diff --git a/Examples/Messaging/Samples.Messaging.WolverineRabbitMq/TestEvent.cs b/Examples/Messaging/Examples.Messaging.Wolverine/TestEvent.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.WolverineRabbitMq/TestEvent.cs rename to Examples/Messaging/Examples.Messaging.Wolverine/TestEvent.cs diff --git a/Examples/Messaging/Samples.Messaging.WolverineRabbitMq/TestEventHandler.cs b/Examples/Messaging/Examples.Messaging.Wolverine/TestEventHandler.cs similarity index 100% rename from Examples/Messaging/Samples.Messaging.WolverineRabbitMq/TestEventHandler.cs rename to Examples/Messaging/Examples.Messaging.Wolverine/TestEventHandler.cs diff --git a/Src/RCommon.ApplicationServices/CqrsBuilder.cs b/Src/RCommon.ApplicationServices/CqrsBuilder.cs index 27ea4c4e..da489daa 100644 --- a/Src/RCommon.ApplicationServices/CqrsBuilder.cs +++ b/Src/RCommon.ApplicationServices/CqrsBuilder.cs @@ -23,7 +23,7 @@ protected void RegisterServices(IServiceCollection services) { services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); // TODO: Allow CQRS configuration to choose caching strategy } public IServiceCollection Services { get; } diff --git a/Src/RCommon.ApplicationServices/RCommon.ApplicationServices.csproj b/Src/RCommon.ApplicationServices/RCommon.ApplicationServices.csproj index 980f155b..df04c79b 100644 --- a/Src/RCommon.ApplicationServices/RCommon.ApplicationServices.csproj +++ b/Src/RCommon.ApplicationServices/RCommon.ApplicationServices.csproj @@ -10,7 +10,7 @@ A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. Jason Webb RCommon - 2.0.0.4 + 2.0.0.5 GitHub RCommon, application services, CQRS, auto web api, commands, command handlers, queries, query handlers, command bus, query bus, c#, .NET Apache-2.0 diff --git a/Src/RCommon.Authorization.Web/RCommon.Authorization.Web.csproj b/Src/RCommon.Authorization.Web/RCommon.Authorization.Web.csproj index d6b88037..d95043f9 100644 --- a/Src/RCommon.Authorization.Web/RCommon.Authorization.Web.csproj +++ b/Src/RCommon.Authorization.Web/RCommon.Authorization.Web.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Core/EventHandling/EventHandlingBuilderExtensions.cs b/Src/RCommon.Core/EventHandling/EventHandlingBuilderExtensions.cs index 6a4f29d2..b1a561a5 100644 --- a/Src/RCommon.Core/EventHandling/EventHandlingBuilderExtensions.cs +++ b/Src/RCommon.Core/EventHandling/EventHandlingBuilderExtensions.cs @@ -33,13 +33,13 @@ public static IRCommonBuilder WithEventHandling(this IRCommonBuilder builder, public static void AddProducer(this IEventHandlingBuilder builder) where T : class, IEventProducer { - builder.Services.TryAddSingleton(); + builder.Services.AddSingleton(); } public static void AddProducer(this IEventHandlingBuilder builder, Func getProducer) where T : class, IEventProducer { - builder.Services.TryAddSingleton(getProducer); + builder.Services.AddSingleton(getProducer); } public static void AddProducer(this IEventHandlingBuilder builder, T producer) @@ -55,14 +55,14 @@ public static void AddProducer(this IEventHandlingBuilder builder, T producer } public static void AddSubscriber(this IEventHandlingBuilder builder) - where TEvent : class + where TEvent : class, ISerializableEvent where TEventHandler : class, ISubscriber { builder.Services.AddScoped, TEventHandler>(); } public static void AddSubscriber(this IEventHandlingBuilder builder, Func getSubscriber) - where TEvent : class + where TEvent : class, ISerializableEvent where TEventHandler : class, ISubscriber { builder.Services.TryAddScoped(getSubscriber); diff --git a/Src/RCommon.Core/EventHandling/Producers/IEventProducer.cs b/Src/RCommon.Core/EventHandling/Producers/IEventProducer.cs index b40c262c..7a628873 100644 --- a/Src/RCommon.Core/EventHandling/Producers/IEventProducer.cs +++ b/Src/RCommon.Core/EventHandling/Producers/IEventProducer.cs @@ -9,6 +9,7 @@ namespace RCommon.EventHandling.Producers { public interface IEventProducer { - Task ProduceEventAsync(T @event, CancellationToken cancellationToken = default) where T : ISerializableEvent; + Task ProduceEventAsync(TEvent @event, CancellationToken cancellationToken = default) + where TEvent : ISerializableEvent; } } diff --git a/Src/RCommon.Core/EventHandling/Producers/IEventRouter.cs b/Src/RCommon.Core/EventHandling/Producers/IEventRouter.cs index 78cb4030..8cef68d3 100644 --- a/Src/RCommon.Core/EventHandling/Producers/IEventRouter.cs +++ b/Src/RCommon.Core/EventHandling/Producers/IEventRouter.cs @@ -22,7 +22,7 @@ public interface IEventRouter /// for events and events. /// /// Async Task Result - Task RouteEvents(); + Task RouteEventsAsync(); /// /// Wires up all of the event producers for all events passed into parameters and then executes each @@ -32,6 +32,6 @@ public interface IEventRouter /// producers that are registered. /// Async Task Result /// This will not send stored transactional events, only the events sent through the parameter. - Task RouteEvents(IEnumerable transactionalEvents); + Task RouteEventsAsync(IEnumerable transactionalEvents); } } \ No newline at end of file diff --git a/Src/RCommon.Core/EventHandling/Producers/InMemoryTransactionalEventRouter.cs b/Src/RCommon.Core/EventHandling/Producers/InMemoryTransactionalEventRouter.cs index b79bad19..6e0075c1 100644 --- a/Src/RCommon.Core/EventHandling/Producers/InMemoryTransactionalEventRouter.cs +++ b/Src/RCommon.Core/EventHandling/Producers/InMemoryTransactionalEventRouter.cs @@ -26,7 +26,7 @@ public InMemoryTransactionalEventRouter(IServiceProvider serviceProvider, ILogge _storedTransactionalEvents = new List(); } - public async Task RouteEvents(IEnumerable transactionalEvents) + public async Task RouteEventsAsync(IEnumerable transactionalEvents) { try { @@ -63,9 +63,9 @@ public async Task RouteEvents(IEnumerable transactionalEvent } } - public async Task RouteEvents() + public async Task RouteEventsAsync() { - await this.RouteEvents(this._storedTransactionalEvents); + await this.RouteEventsAsync(this._storedTransactionalEvents); this._storedTransactionalEvents.Clear(); } diff --git a/Src/RCommon.Core/EventHandling/Subscribers/ISubscriber.cs b/Src/RCommon.Core/EventHandling/Subscribers/ISubscriber.cs index 924617fa..3fa16853 100644 --- a/Src/RCommon.Core/EventHandling/Subscribers/ISubscriber.cs +++ b/Src/RCommon.Core/EventHandling/Subscribers/ISubscriber.cs @@ -10,8 +10,8 @@ namespace RCommon.EventHandling.Subscribers { - public interface ISubscriber + public interface ISubscriber { - public Task HandleAsync(TLocalEvent localEvent, CancellationToken cancellationToken = default); + public Task HandleAsync(TEvent @event, CancellationToken cancellationToken = default); } } diff --git a/Src/RCommon.Core/RCommon.Core.csproj b/Src/RCommon.Core/RCommon.Core.csproj index 0807f3eb..a39b1051 100644 --- a/Src/RCommon.Core/RCommon.Core.csproj +++ b/Src/RCommon.Core/RCommon.Core.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Dapper/RCommon.Dapper.csproj b/Src/RCommon.Dapper/RCommon.Dapper.csproj index 494aef27..8150928a 100644 --- a/Src/RCommon.Dapper/RCommon.Dapper.csproj +++ b/Src/RCommon.Dapper/RCommon.Dapper.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.EfCore/RCommon.EFCore.csproj b/Src/RCommon.EfCore/RCommon.EFCore.csproj index 36511f3d..0db368bf 100644 --- a/Src/RCommon.EfCore/RCommon.EFCore.csproj +++ b/Src/RCommon.EfCore/RCommon.EFCore.csproj @@ -3,7 +3,7 @@ enable net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.EfCore/RCommonDbContext.cs b/Src/RCommon.EfCore/RCommonDbContext.cs index afa0a110..cd242dc5 100644 --- a/Src/RCommon.EfCore/RCommonDbContext.cs +++ b/Src/RCommon.EfCore/RCommonDbContext.cs @@ -15,10 +15,10 @@ namespace RCommon.Persistence.EFCore { public abstract class RCommonDbContext : DbContext, IDataStore { - private readonly IEntityEventTracker _eventTracker; + private readonly IEntityEventTracker _entityEventTracker; - public RCommonDbContext(DbContextOptions options, IEntityEventTracker eventTracker) + public RCommonDbContext(DbContextOptions options, IEntityEventTracker entityEventTracker) : base(options) { if (options is null) @@ -26,7 +26,7 @@ public RCommonDbContext(DbContextOptions options, IEntityEventTracker eventTrack throw new ArgumentNullException(nameof(options)); } - this._eventTracker = eventTracker ?? throw new ArgumentNullException(nameof(eventTracker)); + this._entityEventTracker = entityEventTracker ?? throw new ArgumentNullException(nameof(entityEventTracker)); } public RCommonDbContext(DbContextOptions options) @@ -50,7 +50,7 @@ public virtual void PersistChanges() public override async Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { - this._eventTracker.PublishLocalEvents(); + await this._entityEventTracker.EmitTransactionalEventsAsync(); return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } } diff --git a/Src/RCommon.Emailing/RCommon.Emailing.csproj b/Src/RCommon.Emailing/RCommon.Emailing.csproj index c3277ce2..56963c6b 100644 --- a/Src/RCommon.Emailing/RCommon.Emailing.csproj +++ b/Src/RCommon.Emailing/RCommon.Emailing.csproj @@ -13,7 +13,7 @@ RCommon, emailing, email abstractions, smtp true GitHub - 2.0.0.4 + 2.0.0.5 Apache-2.0 diff --git a/Src/RCommon.Entities/IEntityEventTracker.cs b/Src/RCommon.Entities/IEntityEventTracker.cs index 94f88a3f..8f73e508 100644 --- a/Src/RCommon.Entities/IEntityEventTracker.cs +++ b/Src/RCommon.Entities/IEntityEventTracker.cs @@ -21,6 +21,6 @@ public interface IEntityEventTracker /// Publishes the events associated with each entity being tracked. /// /// True if successful - Task PublishLocalEvents(); + Task EmitTransactionalEventsAsync(); } } diff --git a/Src/RCommon.Entities/InMemoryEntityEventTracker.cs b/Src/RCommon.Entities/InMemoryEntityEventTracker.cs index 50f1ede1..1708d66b 100644 --- a/Src/RCommon.Entities/InMemoryEntityEventTracker.cs +++ b/Src/RCommon.Entities/InMemoryEntityEventTracker.cs @@ -30,7 +30,7 @@ public void AddEntity(IBusinessEntity entity) public ICollection TrackedEntities { get => _businessEntities; } - public async Task PublishLocalEvents() + public async Task EmitTransactionalEventsAsync() { foreach (var entity in this._businessEntities) { @@ -38,11 +38,11 @@ public async Task PublishLocalEvents() foreach (var graphEntity in entityGraph) { - await _eventRouter.RouteEvents(graphEntity.LocalEvents); + _eventRouter.AddTransactionalEvents(graphEntity.LocalEvents); } } + await _eventRouter.RouteEventsAsync(); return true; - } } } diff --git a/Src/RCommon.Entities/RCommon.Entities.csproj b/Src/RCommon.Entities/RCommon.Entities.csproj index 33b3d2e5..16076363 100644 --- a/Src/RCommon.Entities/RCommon.Entities.csproj +++ b/Src/RCommon.Entities/RCommon.Entities.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Linq2Db/RCommon.Linq2Db.csproj b/Src/RCommon.Linq2Db/RCommon.Linq2Db.csproj index 32b97f94..e65af018 100644 --- a/Src/RCommon.Linq2Db/RCommon.Linq2Db.csproj +++ b/Src/RCommon.Linq2Db/RCommon.Linq2Db.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Linq2Db/RCommonDataConnection.cs b/Src/RCommon.Linq2Db/RCommonDataConnection.cs index e7c069f5..63bc2aa3 100644 --- a/Src/RCommon.Linq2Db/RCommonDataConnection.cs +++ b/Src/RCommon.Linq2Db/RCommonDataConnection.cs @@ -2,6 +2,7 @@ using LinqToDB.Configuration; using LinqToDB.Data; using Microsoft.Extensions.Options; +using RCommon.Core.Threading; using RCommon.Entities; using RCommon.Persistence; using System; @@ -34,9 +35,14 @@ public DbConnection GetDbConnection() public void PersistChanges() { - this._eventTracker.PublishLocalEvents(); + AsyncHelper.RunSync(() => this.PersistChangesAsync()); // Nothing to do here because persistence is handled in the underlying API. We'll need to handle Unit of work in a transaction. return; } + + public async Task PersistChangesAsync() + { + await this._eventTracker.EmitTransactionalEventsAsync(); + } } } diff --git a/Src/RCommon.MassTransit/RCommon.MassTransit.csproj b/Src/RCommon.MassTransit/RCommon.MassTransit.csproj index b1018cae..6d2b227a 100644 --- a/Src/RCommon.MassTransit/RCommon.MassTransit.csproj +++ b/Src/RCommon.MassTransit/RCommon.MassTransit.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Mediator/IAppNotificationHandler.cs b/Src/RCommon.Mediator/IAppNotificationHandler.cs deleted file mode 100644 index a591da15..00000000 --- a/Src/RCommon.Mediator/IAppNotificationHandler.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator -{ - public interface IAppNotificationHandler - { - - } - - public interface IAppNotificationHandler : IAppNotificationHandler - { - Task HandleAsync(T notification, CancellationToken cancellationToken = default(CancellationToken)); - } -} diff --git a/Src/RCommon.Mediator/IAppRequestHandler.cs b/Src/RCommon.Mediator/IAppRequestHandler.cs deleted file mode 100644 index d53b9d7f..00000000 --- a/Src/RCommon.Mediator/IAppRequestHandler.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator -{ - public interface IAppRequestHandler - { - Task HandleAsync(TRequest request, CancellationToken cancellationToken); - } -} diff --git a/Src/RCommon.Mediator/IMediatorAdapter.cs b/Src/RCommon.Mediator/IMediatorAdapter.cs new file mode 100644 index 00000000..8911678c --- /dev/null +++ b/Src/RCommon.Mediator/IMediatorAdapter.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.Mediator +{ + public interface IMediatorAdapter + { + + Task Send(TRequest request, CancellationToken cancellationToken = default); + + Task Send(TRequest request, CancellationToken cancellationToken = default); + + Task Publish(TNotification notification, CancellationToken cancellationToken = default); + } +} diff --git a/Src/RCommon.Mediator/IMediatorBuilder.cs b/Src/RCommon.Mediator/IMediatorBuilder.cs index d02db725..1ffd4090 100644 --- a/Src/RCommon.Mediator/IMediatorBuilder.cs +++ b/Src/RCommon.Mediator/IMediatorBuilder.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Extensions.DependencyInjection; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,5 +9,6 @@ namespace RCommon.Mediator { public interface IMediatorBuilder { + IServiceCollection Services { get; } } } diff --git a/Src/RCommon.Mediator/IMediatorService.cs b/Src/RCommon.Mediator/IMediatorService.cs index f1d539d3..cd4df058 100644 --- a/Src/RCommon.Mediator/IMediatorService.cs +++ b/Src/RCommon.Mediator/IMediatorService.cs @@ -1,14 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using RCommon.EventHandling; namespace RCommon.Mediator { public interface IMediatorService { - Task Send(TRequest request, CancellationToken cancellationToken = default); Task Publish(TNotification notification, CancellationToken cancellationToken = default); + + Task Send(TRequest request, CancellationToken cancellationToken = default); + + Task Send(TRequest request, CancellationToken cancellationToken = default); } -} +} \ No newline at end of file diff --git a/Src/RCommon.Mediator/MediatorBuilderExtensions.cs b/Src/RCommon.Mediator/MediatorBuilderExtensions.cs index 6e3dc7a5..50e6d6aa 100644 --- a/Src/RCommon.Mediator/MediatorBuilderExtensions.cs +++ b/Src/RCommon.Mediator/MediatorBuilderExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; using RCommon.EventHandling; using RCommon.Mediator; using System; @@ -12,18 +13,23 @@ namespace RCommon { public static class MediatorBuilderExtensions { - public static void AddEvent(this IEventHandlingBuilder config) - where T : class, ISerializableEvent, IAppNotification + public static IRCommonBuilder WithMediator(this IRCommonBuilder builder) + where T : IMediatorBuilder { - config.Services.TryAddTransient(); + return WithMediator(builder, x => { }); } - public static void AddEvent(this IEventHandlingBuilder config, Func getEvent) - where T : class, ISerializableEvent, IAppNotification + public static IRCommonBuilder WithMediator(this IRCommonBuilder builder, Action actions) + where T : IMediatorBuilder { - config.Services.TryAddTransient(getEvent); + + builder.Services.AddSingleton(); + + // Event Handling Configurations + var mediatorConfig = (T)Activator.CreateInstance(typeof(T), new object[] { builder }); + actions(mediatorConfig); + return builder; } - } } diff --git a/Src/RCommon.Mediator/MediatorService.cs b/Src/RCommon.Mediator/MediatorService.cs new file mode 100644 index 00000000..49d17872 --- /dev/null +++ b/Src/RCommon.Mediator/MediatorService.cs @@ -0,0 +1,35 @@ +using RCommon.EventHandling; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.Mediator +{ + public class MediatorService : IMediatorService + { + private readonly IMediatorAdapter _mediatorAdapter; + + public MediatorService(IMediatorAdapter mediatorAdapter) + { + _mediatorAdapter = mediatorAdapter; + } + + public Task Publish(TNotification notification, CancellationToken cancellationToken = default) + { + return _mediatorAdapter.Publish(notification, cancellationToken); + } + + public async Task Send(TRequest request, CancellationToken cancellationToken = default) + { + await _mediatorAdapter.Send(request, cancellationToken); + } + + public async Task Send(TRequest request, CancellationToken cancellationToken = default) + { + return await _mediatorAdapter.Send(request, cancellationToken); + } + + } +} diff --git a/Src/RCommon.Mediator/Producers/PublishWithMediatorEventProducer.cs b/Src/RCommon.Mediator/Producers/PublishWithMediatorEventProducer.cs deleted file mode 100644 index c933e367..00000000 --- a/Src/RCommon.Mediator/Producers/PublishWithMediatorEventProducer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using RCommon.EventHandling; -using RCommon.EventHandling.Producers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator.Producers -{ - public class PublishWithMediatorEventProducer : IEventProducer - { - private readonly IMediatorService _mediatorService; - - public PublishWithMediatorEventProducer(IMediatorService mediatorService) - { - _mediatorService = mediatorService; - } - - public async Task ProduceEventAsync(T @event, CancellationToken cancellationToken = default) - where T : ISerializableEvent - { - await _mediatorService.Publish(@event, cancellationToken); - } - } -} diff --git a/Src/RCommon.Mediator/Producers/SendWithMediatorEventProducer.cs b/Src/RCommon.Mediator/Producers/SendWithMediatorEventProducer.cs deleted file mode 100644 index 8dd6de41..00000000 --- a/Src/RCommon.Mediator/Producers/SendWithMediatorEventProducer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using RCommon.EventHandling; -using RCommon.EventHandling.Producers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator.Producers -{ - public class SendWithMediatorEventProducer : IEventProducer - { - private readonly IMediatorService _mediatorService; - - public SendWithMediatorEventProducer(IMediatorService mediatorService) - { - _mediatorService = mediatorService; - } - - public Task ProduceEventAsync(T @event, CancellationToken cancellationToken = default) - where T : ISerializableEvent - { - throw new NotImplementedException(); - } - } -} diff --git a/Src/RCommon.Mediator/RCommon.Mediator.csproj b/Src/RCommon.Mediator/RCommon.Mediator.csproj index 7d24b343..6491e620 100644 --- a/Src/RCommon.Mediator/RCommon.Mediator.csproj +++ b/Src/RCommon.Mediator/RCommon.Mediator.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Mediator/IAppNotification.cs b/Src/RCommon.Mediator/Subscribers/IAppNotification.cs similarity index 81% rename from Src/RCommon.Mediator/IAppNotification.cs rename to Src/RCommon.Mediator/Subscribers/IAppNotification.cs index 0222b494..af53b9f0 100644 --- a/Src/RCommon.Mediator/IAppNotification.cs +++ b/Src/RCommon.Mediator/Subscribers/IAppNotification.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace RCommon.Mediator +namespace RCommon.Mediator.Subscribers { public interface IAppNotification { diff --git a/Src/RCommon.Mediator/IAppRequest.cs b/Src/RCommon.Mediator/Subscribers/IAppRequest.cs similarity index 63% rename from Src/RCommon.Mediator/IAppRequest.cs rename to Src/RCommon.Mediator/Subscribers/IAppRequest.cs index 34e790c8..d47b4ef4 100644 --- a/Src/RCommon.Mediator/IAppRequest.cs +++ b/Src/RCommon.Mediator/Subscribers/IAppRequest.cs @@ -4,9 +4,15 @@ using System.Text; using System.Threading.Tasks; -namespace RCommon.Mediator +namespace RCommon.Mediator.Subscribers { public interface IAppRequest { + + } + + public interface IAppRequest + { + } } diff --git a/Src/RCommon.Mediator/Subscribers/IAppRequestHandler.cs b/Src/RCommon.Mediator/Subscribers/IAppRequestHandler.cs new file mode 100644 index 00000000..8601d600 --- /dev/null +++ b/Src/RCommon.Mediator/Subscribers/IAppRequestHandler.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.Mediator.Subscribers +{ + public interface IAppRequestHandler + { + public Task HandleAsync(TRequest request, CancellationToken cancellationToken = default); + } + + public interface IAppRequestHandler + { + public Task HandleAsync(TRequest request, CancellationToken cancellationToken = default); + } +} diff --git a/Src/RCommon.Mediatr/Behaviors/DistributedUnitOfWorkBehavior.cs b/Src/RCommon.Mediatr/Behaviors/DistributedUnitOfWorkBehavior.cs deleted file mode 100644 index f6bbba64..00000000 --- a/Src/RCommon.Mediatr/Behaviors/DistributedUnitOfWorkBehavior.cs +++ /dev/null @@ -1,62 +0,0 @@ -using MediatR; -using Microsoft.Extensions.Logging; -using System; -using System.Threading; -using System.Threading.Tasks; -using RCommon.Persistence.Transactions; -using RCommon.EventHandling.Producers; - -namespace RCommon.Mediator.MediatR.Behaviors -{ - public class DistributedUnitOfWorkBehavior : IPipelineBehavior - where TRequest : IRequest - { - private readonly ILogger> _logger; - private readonly IEventProducer _distributedEventBroker; - private readonly IUnitOfWorkFactory _unitOfWorkScopeFactory; - private readonly IUnitOfWorkManager _unitOfWorkManager; - - public DistributedUnitOfWorkBehavior(IUnitOfWorkFactory unitOfWorkScopeFactory, IUnitOfWorkManager unitOfWorkManager, - ILogger> logger, IEventProducer distributedEventBroker) - { - _unitOfWorkScopeFactory = unitOfWorkScopeFactory ?? throw new ArgumentException(nameof(IUnitOfWorkFactory)); - _unitOfWorkManager = unitOfWorkManager ?? throw new ArgumentException(nameof(IUnitOfWorkManager)); - _logger = logger ?? throw new ArgumentException(nameof(ILogger)); - _distributedEventBroker = distributedEventBroker ?? throw new ArgumentNullException(nameof(distributedEventBroker)); - } - - public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) - { - var response = default(TResponse); - var typeName = request.GetGenericTypeName(); - - try - { - using (var unitOfWork = this._unitOfWorkScopeFactory.Create(TransactionMode.Default)) - { - _logger.LogInformation("----- Begin transaction {UnitOfWorkTransactionId} for {CommandName} ({@Command})", - this._unitOfWorkManager.CurrentUnitOfWork.TransactionId, typeName, request); - - response = await next(); - - _logger.LogInformation("----- Commit transaction {UnitOfWorkTransactionId} for {CommandName}", - this._unitOfWorkManager.CurrentUnitOfWork.TransactionId, typeName); - - unitOfWork.Commit(); - } - - //Perform MassTransit publish events - //await _distributedEventBroker.PublishDistributedEvents(cancellationToken); - - - return response; - } - catch (ApplicationException ex) - { - _logger.LogError(ex, "ERROR Handling transaction for {CommandName} ({@Command})", typeName, request); - - throw; - } - } - } -} diff --git a/Src/RCommon.Mediatr/Behaviors/ValidatorBehavior.cs b/Src/RCommon.Mediatr/Behaviors/ValidatorBehavior.cs index ac5959cb..15c3ad3c 100644 --- a/Src/RCommon.Mediatr/Behaviors/ValidatorBehavior.cs +++ b/Src/RCommon.Mediatr/Behaviors/ValidatorBehavior.cs @@ -1,7 +1,6 @@ using FluentValidation; using MediatR; using Microsoft.Extensions.Logging; - using System; using System.Collections.Generic; using System.Linq; diff --git a/Src/RCommon.Mediatr/IMediatRBuilder.cs b/Src/RCommon.Mediatr/IMediatRBuilder.cs index c286ab5c..2fd4fb4e 100644 --- a/Src/RCommon.Mediatr/IMediatRBuilder.cs +++ b/Src/RCommon.Mediatr/IMediatRBuilder.cs @@ -1,16 +1,10 @@ using Microsoft.Extensions.DependencyInjection; -using RCommon.Mediator; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace RCommon.Mediator.MediatR { public interface IMediatRBuilder : IMediatorBuilder { - IMediatRBuilder AddMediatr(Action options); - IMediatRBuilder AddMediatr(MediatRServiceConfiguration options); + IMediatRBuilder Configure(Action options); + IMediatRBuilder Configure(MediatRServiceConfiguration options); } } diff --git a/Src/RCommon.Mediatr/IMediatREventHandlingBuilder.cs b/Src/RCommon.Mediatr/IMediatREventHandlingBuilder.cs new file mode 100644 index 00000000..0ed64089 --- /dev/null +++ b/Src/RCommon.Mediatr/IMediatREventHandlingBuilder.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.DependencyInjection; +using RCommon.EventHandling; + +namespace RCommon.MediatR +{ + public interface IMediatREventHandlingBuilder : IEventHandlingBuilder + { + + } +} diff --git a/Src/RCommon.Mediatr/INotificationHandler.cs b/Src/RCommon.Mediatr/INotificationHandler.cs deleted file mode 100644 index 052aae95..00000000 --- a/Src/RCommon.Mediatr/INotificationHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -using MediatR; - -namespace RCommon.Mediator.MediatR -{ - public interface INotificationHandler : INotificationHandler - where TNotification : MediatRNotification - { - } -} \ No newline at end of file diff --git a/Src/RCommon.Mediatr/MediatRAdapter.cs b/Src/RCommon.Mediatr/MediatRAdapter.cs new file mode 100644 index 00000000..82bb20ee --- /dev/null +++ b/Src/RCommon.Mediatr/MediatRAdapter.cs @@ -0,0 +1,49 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using RCommon.Mediator; +using RCommon.MediatR.Subscribers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.MediatR +{ + /// + /// An Adapter for + /// + public class MediatRAdapter : IMediatorAdapter + { + private readonly IMediator _mediator; + + public MediatRAdapter(IMediator mediator) + { + _mediator = mediator; + } + + /// + /// This will wrap the original notification in and then publish it + /// using + /// + /// + /// + /// + /// This should raise which is the + /// default handler for the wrapped notification + public Task Publish(TNotification notification, CancellationToken cancellationToken = default) + { + return _mediator.Publish(new MediatRNotification(notification), cancellationToken); + } + + public async Task Send(TRequest request, CancellationToken cancellationToken = default) + { + await _mediator.Send(new MediatRRequest(request), cancellationToken); + } + + public async Task Send(TRequest request, CancellationToken cancellationToken = default) + { + return await _mediator.Send(new MediatRRequest(request), cancellationToken); + } + } +} diff --git a/Src/RCommon.Mediatr/MediatRBuilder.cs b/Src/RCommon.Mediatr/MediatRBuilder.cs index 65b635e4..d7a65b6a 100644 --- a/Src/RCommon.Mediatr/MediatRBuilder.cs +++ b/Src/RCommon.Mediatr/MediatRBuilder.cs @@ -1,8 +1,13 @@ -using Microsoft.Extensions.DependencyInjection; +using MediatR; +using Microsoft.Extensions.DependencyInjection; +using RCommon.EventHandling.Subscribers; using RCommon.Mediator; +using RCommon.MediatR; +using RCommon.MediatR.Subscribers; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -10,23 +15,38 @@ namespace RCommon.Mediator.MediatR { public class MediatRBuilder : IMediatRBuilder { - private readonly IServiceCollection _services; - public MediatRBuilder(IServiceCollection services) + public MediatRBuilder(IRCommonBuilder builder) { - _services = services ?? throw new ArgumentNullException(nameof(services)); + + + this.RegisterServices(builder.Services); + Services = builder.Services; + + } + + protected void RegisterServices(IServiceCollection services) + { + services.AddSingleton(); + + services.AddMediatR(options => + { + options.RegisterServicesFromAssemblies((typeof(MediatRBuilder).GetTypeInfo().Assembly)); + }); } - public IMediatRBuilder AddMediatr(Action options) + public IMediatRBuilder Configure(Action options) { - this._services.AddMediatR(options); + Services.AddMediatR(options); return this; } - public IMediatRBuilder AddMediatr(MediatRServiceConfiguration options) + public IMediatRBuilder Configure(MediatRServiceConfiguration options) { - this._services.AddMediatR(options); + Services.AddMediatR(options); return this; } + + public IServiceCollection Services { get; } } } diff --git a/Src/RCommon.Mediatr/MediatRBuilderExtensions.cs b/Src/RCommon.Mediatr/MediatRBuilderExtensions.cs index eaab0c5a..2e1c2a45 100644 --- a/Src/RCommon.Mediatr/MediatRBuilderExtensions.cs +++ b/Src/RCommon.Mediatr/MediatRBuilderExtensions.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using RCommon.EventHandling; +using RCommon.EventHandling.Subscribers; using RCommon.Mediator; using RCommon.Mediator.MediatR; using RCommon.Mediator.MediatR.Behaviors; +using RCommon.Mediator.Subscribers; +using RCommon.MediatR.Subscribers; using System; using System.Collections.Generic; using System.Text; @@ -15,34 +18,52 @@ public static class MediatRBuilderExtensions { - public static IRCommonBuilder AddMediatR(this IRCommonBuilder config, Action mediatrOptions ) + public static void AddNotification(this IMediatRBuilder builder) + where T : class, IAppNotification + where TEventHandler : class, ISubscriber { - config.Services.AddMediatR(mediatrOptions); - return config; + builder.Services.AddTransient, TEventHandler>(); + + // For notifications which can be handled by multiple handlers + builder.Services.AddTransient>, MediatRNotificationHandler>>(); + } + + public static void AddRequest(this IMediatRBuilder builder) + where TRequest : class, IAppRequest + where TEventHandler : class, IAppRequestHandler + { + builder.Services.AddTransient, TEventHandler>(); + + // For requests which only have one endpoint. This should only be raised if we use the IMediator.Send method + builder.Services.AddTransient>, + MediatRRequestHandler>>(); } - public static IRCommonBuilder AddLoggingToMediatorPipeline(this IRCommonBuilder config) + public static void AddRequest(this IMediatRBuilder builder) + where TRequest : class, IAppRequest + where TResponse : class + where TEventHandler : class, IAppRequestHandler { - config.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); - return config; + builder.Services.AddTransient, TEventHandler>(); + + // For requests which only have one endpoint. This should only be raised if we use the IMediator.Send method + builder.Services.AddTransient, TResponse>, + MediatRRequestHandler, TResponse>>(); } - public static IRCommonBuilder AddValidationToMediatorPipeline(this IRCommonBuilder config) + public static void AddLoggingToRequestPipeline(this IMediatRBuilder builder) { - config.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>)); - return config; + builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); } - public static IRCommonBuilder AddUnitOfWorkToMediatorPipeline(this IRCommonBuilder config) + public static void AddValidationToRequestPipeline(this IMediatRBuilder builder) { - config.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnitOfWorkBehavior<,>)); - return config; + builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>)); } - public static IRCommonBuilder AddDisributedUnitOfWorkToMediatorPipeline(this IRCommonBuilder config) + public static void AddUnitOfWorkToRequestPipeline(this IMediatRBuilder builder) { - config.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(DistributedUnitOfWorkBehavior<,>)); - return config; + builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnitOfWorkBehavior<,>)); } } diff --git a/Src/RCommon.Mediatr/MediatREventHandlingBuilder.cs b/Src/RCommon.Mediatr/MediatREventHandlingBuilder.cs index 9bb54a32..8d33ad90 100644 --- a/Src/RCommon.Mediatr/MediatREventHandlingBuilder.cs +++ b/Src/RCommon.Mediatr/MediatREventHandlingBuilder.cs @@ -3,6 +3,7 @@ using RCommon.EventHandling; using RCommon.Mediator; using RCommon.Mediator.MediatR; +using RCommon.MediatR.Subscribers; using System; using System.Collections.Generic; using System.Linq; @@ -12,26 +13,21 @@ namespace RCommon.MediatR { - public class MediatREventHandlingBuilder : IEventHandlingBuilder + public class MediatREventHandlingBuilder : IMediatREventHandlingBuilder { - public MediatREventHandlingBuilder(IServiceCollection services) + public MediatREventHandlingBuilder(IRCommonBuilder builder) { - Services = services; - this.RegisterServices(services); + + + this.RegisterServices(builder.Services); + Services = builder.Services; + } protected void RegisterServices(IServiceCollection services) - { - services.AddMediatR(mediatr => - { - mediatr.RegisterServicesFromAssemblyContaining(); - }); + { - - services.AddSingleton(); - //services.AddTransient(typeof(INotificationHandler<>), typeof(INotificationHandler<,>)); - services.AddTransient(typeof(INotificationHandler<,>), typeof(MediatRNotificationHandler<,>)); - services.AddTransient(typeof(IRequestHandler<,>), typeof(MediatRRequestHandler<,>)); + services.AddSingleton(); } public IServiceCollection Services { get; } diff --git a/Src/RCommon.Mediatr/MediatREventHandlingBuilderExtensions.cs b/Src/RCommon.Mediatr/MediatREventHandlingBuilderExtensions.cs index cfe51477..cfb7b287 100644 --- a/Src/RCommon.Mediatr/MediatREventHandlingBuilderExtensions.cs +++ b/Src/RCommon.Mediatr/MediatREventHandlingBuilderExtensions.cs @@ -1,11 +1,16 @@ -using Microsoft.Extensions.DependencyInjection; +using MediatR; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using RCommon.EventHandling; +using RCommon.EventHandling.Subscribers; using RCommon.Mediator; using RCommon.Mediator.MediatR; +using RCommon.Mediator.Subscribers; +using RCommon.MediatR.Subscribers; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -13,20 +18,48 @@ namespace RCommon.MediatR { public static class MediatREventHandlingBuilderExtensions { - public static void AddSubscriber(this IEventHandlingBuilder config) - where TEventHandler : class, IAppNotificationHandler - where TEvent : IAppNotification + public static IRCommonBuilder WithEventHandling(this IRCommonBuilder builder) + where T : IMediatREventHandlingBuilder { - //config.Services.AddTransient(typeof(IAppNotificationHandler<>), typeof(TEventHandler<>)); - //config.Services.AddTransient, TEventHandler>(); - config.Services.AddTransient, TEventHandler>(); + return WithEventHandling(builder, x => { }, x=> { }); } - public static void AddSubscriber(this IEventHandlingBuilder config, Func getSubscriber) - where TEventHandler : class, IAppNotificationHandler - where TEvent : IAppNotification + public static IRCommonBuilder WithEventHandling(this IRCommonBuilder builder, Action actions) + where T : IMediatREventHandlingBuilder { - config.Services.TryAddTransient(getSubscriber); + // MediatR + WithEventHandling(builder, actions, mediatrActions => + { + mediatrActions.RegisterServicesFromAssemblies((typeof(MediatRBuilder).GetTypeInfo().Assembly)); + }); + + return builder; + } + + public static IRCommonBuilder WithEventHandling(this IRCommonBuilder builder, Action actions, + Action mediatRActions) + where T : IMediatREventHandlingBuilder + { + builder.Services.AddTransient(); + + // MediatR + builder.Services.AddMediatR(mediatRActions); + + // This will wire up common event handling + var eventHandlingConfig = (T)Activator.CreateInstance(typeof(T), new object[] { builder }); + actions(eventHandlingConfig); + + return builder; + } + + public static void AddSubscriber(this IMediatREventHandlingBuilder builder) + where TEvent : class, ISerializableEvent + where TEventHandler : class, ISubscriber + { + builder.Services.AddTransient, TEventHandler>(); + + // For notifications which can be handled by multiple handlers + builder.Services.AddTransient>, MediatREventHandler>>(); } } } diff --git a/Src/RCommon.Mediatr/MediatRNotificationHandler.cs b/Src/RCommon.Mediatr/MediatRNotificationHandler.cs deleted file mode 100644 index 07c39edd..00000000 --- a/Src/RCommon.Mediatr/MediatRNotificationHandler.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediatR; -using RCommon.EventHandling; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR -{ - public class MediatRNotificationHandler : INotificationHandler - where TNotification : MediatRNotification - { - private readonly IAppNotificationHandler _handlers; - - //the IoC should inject all handlers here - public MediatRNotificationHandler(IAppNotificationHandler handlers) - { - _handlers = handlers ?? throw new ArgumentNullException(nameof(handlers)); - } - - - - public Task Handle(TNotification notification, CancellationToken cancellationToken) - { - var tasks = _handlers.HandleAsync(notification.Notification, cancellationToken); - //.Select(x => x.HandleAsync(notification.Notification, cancellationToken)); - return Task.WhenAll(tasks); - } - } -} diff --git a/Src/RCommon.Mediatr/MediatRRequest.cs b/Src/RCommon.Mediatr/MediatRRequest.cs deleted file mode 100644 index 1f0e6adc..00000000 --- a/Src/RCommon.Mediatr/MediatRRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using MediatR; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR -{ - public class MediatRRequest : IRequest - { - - public MediatRRequest(TRequest request) - { - Request = request; - } - - public TRequest Request { get; } - } -} diff --git a/Src/RCommon.Mediatr/MediatRRequestHandler.cs b/Src/RCommon.Mediatr/MediatRRequestHandler.cs deleted file mode 100644 index fcf3197d..00000000 --- a/Src/RCommon.Mediatr/MediatRRequestHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using MediatR; -using RCommon.Mediator; -using RCommon.Mediator.MediatR; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.MediatR -{ - public class MediatRRequestHandler : IRequestHandler, TResponse> - { - private readonly IAppRequestHandler myImpl; - - // injected by DI container - public MediatRRequestHandler(IAppRequestHandler impl) - { - myImpl = impl ?? throw new ArgumentNullException(nameof(impl)); - } - - public Task Handle(MediatRRequest request, CancellationToken cancellationToken) - { - return myImpl.HandleAsync(request.Request, cancellationToken); - } - } -} diff --git a/Src/RCommon.Mediatr/MediatRService.cs b/Src/RCommon.Mediatr/MediatRService.cs deleted file mode 100644 index cd333152..00000000 --- a/Src/RCommon.Mediatr/MediatRService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediatR; -using RCommon.Mediator; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR -{ - public class MediatrService : IMediatorService - { - private readonly IMediator _mediator; - - public MediatrService(IMediator mediator) - { - _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); - } - - public Task Publish(TNotification notification, CancellationToken cancellationToken = default) - - { - return _mediator.Publish(new MediatRNotification(notification), cancellationToken); - } - - public Task Send(TRequest request, CancellationToken cancellationToken = default) - { - return _mediator.Send(new MediatRRequest(request), cancellationToken); - } - } -} diff --git a/Src/RCommon.Mediatr/Producers/PublishWithMediatREventProducer.cs b/Src/RCommon.Mediatr/Producers/PublishWithMediatREventProducer.cs new file mode 100644 index 00000000..843d3c01 --- /dev/null +++ b/Src/RCommon.Mediatr/Producers/PublishWithMediatREventProducer.cs @@ -0,0 +1,30 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.EventHandling.Producers; +using RCommon.Mediator; +using RCommon.MediatR.Subscribers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.MediatR.Producers +{ + public class PublishWithMediatREventProducer : IEventProducer + { + private readonly IMediatorService _mediatorService; + + public PublishWithMediatREventProducer(IMediatorService mediatorService) + { + _mediatorService = mediatorService; + } + + public async Task ProduceEventAsync(TEvent @event, CancellationToken cancellationToken = default) + where TEvent : ISerializableEvent + { + Guard.IsNotNull(@event, nameof(@event)); + await _mediatorService.Publish(@event, cancellationToken); + } + } +} diff --git a/Src/RCommon.Mediatr/Producers/SendWithMediatREventProducer.cs b/Src/RCommon.Mediatr/Producers/SendWithMediatREventProducer.cs new file mode 100644 index 00000000..e0a55594 --- /dev/null +++ b/Src/RCommon.Mediatr/Producers/SendWithMediatREventProducer.cs @@ -0,0 +1,30 @@ +using RCommon.EventHandling; +using RCommon.EventHandling.Producers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediatR; +using RCommon.MediatR.Subscribers; +using RCommon.Mediator; + +namespace RCommon.MediatR.Producers +{ + public class SendWithMediatREventProducer : IEventProducer + { + private readonly IMediatorService _mediatorService; + + public SendWithMediatREventProducer(IMediatorService mediatorService) + { + _mediatorService = mediatorService; + } + + public async Task ProduceEventAsync(TEvent @event, CancellationToken cancellationToken = default) + where TEvent : ISerializableEvent + { + Guard.IsNotNull(@event, nameof(@event)); + await _mediatorService.Send(@event, cancellationToken); + } + } +} diff --git a/Src/RCommon.Mediatr/RCommon.MediatR.csproj b/Src/RCommon.Mediatr/RCommon.MediatR.csproj index 927ffab0..a2fbd291 100644 --- a/Src/RCommon.Mediatr/RCommon.MediatR.csproj +++ b/Src/RCommon.Mediatr/RCommon.MediatR.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. @@ -11,7 +11,7 @@ https://github.com/Reactor2Team/RCommon rcommon-icon.png RCommon, language extensions, generic factories, abstractions, c#, .NET - false + true 2.0.0.0 2.0.0.0 diff --git a/Src/RCommon.Mediatr/Subscribers/IMediatRNotification.cs b/Src/RCommon.Mediatr/Subscribers/IMediatRNotification.cs new file mode 100644 index 00000000..1bec7aa5 --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/IMediatRNotification.cs @@ -0,0 +1,15 @@ +using MediatR; +using RCommon.Mediator; + +namespace RCommon.MediatR.Subscribers +{ + public interface IMediatRNotification: INotification + { + + } + + public interface IMediatRNotification : IMediatRNotification + { + TEvent Notification { get; set; } + } +} diff --git a/Src/RCommon.Mediatr/Subscribers/IMediatRRequest.cs b/Src/RCommon.Mediatr/Subscribers/IMediatRRequest.cs new file mode 100644 index 00000000..964c9a48 --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/IMediatRRequest.cs @@ -0,0 +1,20 @@ +using MediatR; + +namespace RCommon.MediatR.Subscribers +{ + + public interface IMediatRRequest : IRequest + { + + } + + public interface IMediatRRequest : IRequest, IMediatRRequest + { + + } + + public interface IMediatRRequest : IMediatRRequest + { + TRequest Request { get; } + } +} \ No newline at end of file diff --git a/Src/RCommon.Mediatr/Subscribers/MediatREventHandler.cs b/Src/RCommon.Mediatr/Subscribers/MediatREventHandler.cs new file mode 100644 index 00000000..dccbe26e --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/MediatREventHandler.cs @@ -0,0 +1,38 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.EventHandling.Subscribers; +using RCommon.Mediator.MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using RCommon.Mediator; + +namespace RCommon.MediatR.Subscribers +{ + public class MediatREventHandler : INotificationHandler + where TEvent : class, ISerializableEvent + where TNotification : MediatRNotification + { + private readonly IServiceProvider _serviceProvider; + + public MediatREventHandler(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task Handle(TNotification notification, CancellationToken cancellationToken) + { + // Resolve the actual event handler that we want to execute + var subscriber = (ISubscriber)_serviceProvider.GetService(typeof(ISubscriber)); + + Guard.Against(subscriber == null, + "ISubscriber of type: " + typeof(TEvent).GetGenericTypeName() + " could not be resolved by IServiceProvider"); + + // Handle the event using the event handler we resolved + await subscriber.HandleAsync(notification.Notification); + } + } +} diff --git a/Src/RCommon.Mediatr/MediatRNotification.cs b/Src/RCommon.Mediatr/Subscribers/MediatRNotification.cs similarity index 62% rename from Src/RCommon.Mediatr/MediatRNotification.cs rename to Src/RCommon.Mediatr/Subscribers/MediatRNotification.cs index 52ad3254..7804065f 100644 --- a/Src/RCommon.Mediatr/MediatRNotification.cs +++ b/Src/RCommon.Mediatr/Subscribers/MediatRNotification.cs @@ -5,9 +5,9 @@ using System.Text; using System.Threading.Tasks; -namespace RCommon.Mediator.MediatR +namespace RCommon.MediatR.Subscribers { - public class MediatRNotification : INotification + public class MediatRNotification : IMediatRNotification { public MediatRNotification(TEvent notification) @@ -15,6 +15,6 @@ public MediatRNotification(TEvent notification) Notification = notification; } - public TEvent Notification { get; } + public TEvent Notification { get; set; } } } diff --git a/Src/RCommon.Mediatr/Subscribers/MediatRNotificationHandler.cs b/Src/RCommon.Mediatr/Subscribers/MediatRNotificationHandler.cs new file mode 100644 index 00000000..a5fb4d8e --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/MediatRNotificationHandler.cs @@ -0,0 +1,39 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.EventHandling.Subscribers; +using RCommon.Mediator.MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using RCommon.Mediator; +using RCommon.Mediator.Subscribers; + +namespace RCommon.MediatR.Subscribers +{ + public class MediatRNotificationHandler : INotificationHandler + where T : class, IAppNotification + where TNotification : MediatRNotification + { + private readonly IServiceProvider _serviceProvider; + + public MediatRNotificationHandler(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task Handle(TNotification notification, CancellationToken cancellationToken) + { + // Resolve the actual event handler that we want to execute + var subscriber = (ISubscriber) _serviceProvider.GetService(typeof(ISubscriber)); + + Guard.Against(subscriber == null, + "ISubscriber of type: " + typeof(T).GetGenericTypeName() + " could not be resolved by IServiceProvider"); + + // Handle the event using the event handler we resolved + await subscriber.HandleAsync(notification.Notification); + } + } +} diff --git a/Src/RCommon.Mediatr/Subscribers/MediatRRequest.cs b/Src/RCommon.Mediatr/Subscribers/MediatRRequest.cs new file mode 100644 index 00000000..53b2143a --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/MediatRRequest.cs @@ -0,0 +1,32 @@ +using MediatR; +using RCommon.Mediator; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RCommon.MediatR.Subscribers +{ + public class MediatRRequest : IMediatRRequest + { + + public MediatRRequest(TRequest request) + { + Request = request; + } + + public TRequest Request { get; } + } + + public class MediatRRequest : IMediatRRequest + { + + public MediatRRequest(TRequest request) + { + Request = request; + } + + public TRequest Request { get; } + } +} diff --git a/Src/RCommon.Mediatr/Subscribers/MediatRRequestHandler.cs b/Src/RCommon.Mediatr/Subscribers/MediatRRequestHandler.cs new file mode 100644 index 00000000..912ddd22 --- /dev/null +++ b/Src/RCommon.Mediatr/Subscribers/MediatRRequestHandler.cs @@ -0,0 +1,63 @@ +using MediatR; +using RCommon.EventHandling; +using RCommon.EventHandling.Subscribers; +using RCommon.Mediator.MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using RCommon.Mediator.Subscribers; +using IAppRequest = RCommon.Mediator.Subscribers.IAppRequest; + +namespace RCommon.MediatR.Subscribers +{ + public class MediatRRequestHandler : IRequestHandler + where T : class, IAppRequest + where TRequest : MediatRRequest + { + private readonly IServiceProvider _serviceProvider; + + public MediatRRequestHandler(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task Handle(TRequest request, CancellationToken cancellationToken) + { + // Resolve the actual event handler that we want to execute + var handler = (IAppRequestHandler)_serviceProvider.GetService(typeof(IAppRequestHandler)); + + Guard.Against(handler == null, + "IAppRequestHandler of type: " + typeof(T).GetGenericTypeName() + " could not be resolved by IServiceProvider"); + + // Handle the event using the event handler we resolved + await handler.HandleAsync(request.Request); + } + } + + public class MediatRRequestHandler : IRequestHandler + where T : class, IAppRequest + where TRequest : MediatRRequest + { + private readonly IServiceProvider _serviceProvider; + + public MediatRRequestHandler(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task Handle(TRequest request, CancellationToken cancellationToken) + { + // Resolve the actual event handler that we want to execute + var handler = (IAppRequestHandler)_serviceProvider.GetService(typeof(IAppRequestHandler)); + + Guard.Against(handler == null, + "IAppRequestHandler of type: " + typeof(T).GetGenericTypeName() + " could not be resolved by IServiceProvider"); + + // Handle the event using the event handler we resolved + return await handler.HandleAsync(request.Request); + } + } +} diff --git a/Src/RCommon.Models/RCommon.Models.csproj b/Src/RCommon.Models/RCommon.Models.csproj index 97d5149c..eb6e5e35 100644 --- a/Src/RCommon.Models/RCommon.Models.csproj +++ b/Src/RCommon.Models/RCommon.Models.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Persistence/RCommon.Persistence.csproj b/Src/RCommon.Persistence/RCommon.Persistence.csproj index 8fda7e2d..12d7bd4f 100644 --- a/Src/RCommon.Persistence/RCommon.Persistence.csproj +++ b/Src/RCommon.Persistence/RCommon.Persistence.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Persistence/Sql/RDbConnection.cs b/Src/RCommon.Persistence/Sql/RDbConnection.cs index f6111301..ac52bd19 100644 --- a/Src/RCommon.Persistence/Sql/RDbConnection.cs +++ b/Src/RCommon.Persistence/Sql/RDbConnection.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Options; +using RCommon.Core.Threading; using RCommon.Entities; namespace RCommon.Persistence.Sql @@ -13,12 +14,12 @@ namespace RCommon.Persistence.Sql public class RDbConnection : DisposableResource, IRDbConnection { private readonly IOptions _options; - private readonly IEntityEventTracker _eventTracker; + private readonly IEntityEventTracker _entityEventTracker; - public RDbConnection(IOptions options, IEntityEventTracker eventTracker) + public RDbConnection(IOptions options, IEntityEventTracker entityEventTracker) { _options = options ?? throw new ArgumentNullException(nameof(options)); - this._eventTracker = eventTracker ?? throw new ArgumentNullException(nameof(eventTracker)); + this._entityEventTracker = entityEventTracker ?? throw new ArgumentNullException(nameof(entityEventTracker)); } public DbConnection GetDbConnection() @@ -36,10 +37,15 @@ public DbConnection GetDbConnection() public void PersistChanges() { - this._eventTracker.PublishLocalEvents(); + AsyncHelper.RunSync(() => this.PersistChangesAsync()); // Nothing to do here because this is a SQL Connection return; } + public async Task PersistChangesAsync() + { + await this._entityEventTracker.EmitTransactionalEventsAsync(); + } + } } diff --git a/Src/RCommon.Security/Authorization/AuthorizationException.cs b/Src/RCommon.Security/Authorization/AuthorizationException.cs index 204c21af..89e27d08 100644 --- a/Src/RCommon.Security/Authorization/AuthorizationException.cs +++ b/Src/RCommon.Security/Authorization/AuthorizationException.cs @@ -33,15 +33,6 @@ public AuthorizationException() LogLevel = LogLevel.Warning; } - /// - /// Creates a new object. - /// - public AuthorizationException(SerializationInfo serializationInfo, StreamingContext context) - : base(serializationInfo, context) - { - - } - /// /// Creates a new object. /// diff --git a/Src/RCommon.Security/RCommon.Security.csproj b/Src/RCommon.Security/RCommon.Security.csproj index f13cf435..e1bf992c 100644 --- a/Src/RCommon.Security/RCommon.Security.csproj +++ b/Src/RCommon.Security/RCommon.Security.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.SendGrid/RCommon.SendGrid.csproj b/Src/RCommon.SendGrid/RCommon.SendGrid.csproj index d9cd9302..55985d54 100644 --- a/Src/RCommon.SendGrid/RCommon.SendGrid.csproj +++ b/Src/RCommon.SendGrid/RCommon.SendGrid.csproj @@ -14,7 +14,7 @@ RCommon, emailing, sendgrid true GitHub - 2.0.0.4 + 2.0.0.5 Apache-2.0 diff --git a/Src/RCommon.Web/RCommon.Web.csproj b/Src/RCommon.Web/RCommon.Web.csproj index 25b0ba82..577a844a 100644 --- a/Src/RCommon.Web/RCommon.Web.csproj +++ b/Src/RCommon.Web/RCommon.Web.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Src/RCommon.Wolverine/RCommon.Wolverine.csproj b/Src/RCommon.Wolverine/RCommon.Wolverine.csproj index 6a0d16c0..8384245f 100644 --- a/Src/RCommon.Wolverine/RCommon.Wolverine.csproj +++ b/Src/RCommon.Wolverine/RCommon.Wolverine.csproj @@ -2,7 +2,7 @@ net6.0;net7.0;net8.0; - 2.0.0.4 + 2.0.0.5 Jason Webb RCommon A cohesive set of infrastructure libraries for .NET 6, .NET 7, and .NET 8 that utilizes abstractions for persistence, unit of work/transactions, distributed events, distributed transactions, and more. diff --git a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/DistributedUnitOfWorkBehaviorTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/DistributedUnitOfWorkBehaviorTests.cs deleted file mode 100644 index f073dcca..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/DistributedUnitOfWorkBehaviorTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR.Behaviors; -using System; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR.Tests.Behaviors -{ - /*[TestFixture] - public class DistributedUnitOfWorkBehaviorTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock mockUnitOfWorkFactory; - private Mock mockUnitOfWorkManager; - private Mock>> mockLogger; - private Mock mockDistributedEventPublisher; - - public DistributedUnitOfWorkBehaviorTests() : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockUnitOfWorkFactory = this.mockRepository.Create(); - this.mockUnitOfWorkManager = this.mockRepository.Create(); - this.mockLogger = this.mockRepository.Create>>(); - this.mockDistributedEventPublisher = this.mockRepository.Create(); - } - - private DistributedUnitOfWorkBehavior CreateDistributedUnitOfWorkBehavior() - { - return new DistributedUnitOfWorkBehavior( - this.mockUnitOfWorkFactory.Object, - this.mockUnitOfWorkManager.Object, - this.mockLogger.Object, - this.mockDistributedEventPublisher.Object); - } - - [Test] - public async Task Handle_StateUnderTest_ExpectedBehavior() - { - // Arrange - var distributedUnitOfWorkBehavior = this.CreateDistributedUnitOfWorkBehavior(); - TRequest request = default(TRequest); - RequestHandlerDelegate next = null; - CancellationToken cancellationToken = default(global::System.Threading.CancellationToken); - - // Act - var result = await distributedUnitOfWorkBehavior.Handle( - request, - next, - cancellationToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - }*/ -} diff --git a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/LoggingBehaviorTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/LoggingBehaviorTests.cs deleted file mode 100644 index 808a7f26..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/LoggingBehaviorTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR.Behaviors; -using System; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR.Tests.Behaviors -{ - /*[TestFixture] - public class LoggingBehaviorTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock>> mockLogger; - - public LoggingBehaviorTests() - : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockLogger = this.mockRepository.Create>>(); - } - - private LoggingBehavior CreateLoggingBehavior() - { - return new LoggingBehavior( - this.mockLogger.Object); - } - - [Test] - public async Task Handle_StateUnderTest_ExpectedBehavior() - { - // Arrange - var loggingBehavior = this.CreateLoggingBehavior(); - TRequest request = default(TRequest); - RequestHandlerDelegate next = null; - CancellationToken cancellationToken = default(global::System.Threading.CancellationToken); - - // Act - var result = await loggingBehavior.Handle( - request, - next, - cancellationToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - }*/ -} diff --git a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/UnitOfWorkBehaviorTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/UnitOfWorkBehaviorTests.cs deleted file mode 100644 index 565a452c..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/UnitOfWorkBehaviorTests.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR.Behaviors; -using System; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR.Tests.Behaviors -{ - /* [TestFixture] - public class UnitOfWorkBehaviorTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock mockUnitOfWorkFactory; - private Mock mockUnitOfWorkManager; - private Mock>> mockLogger; - - public UnitOfWorkBehaviorTests() : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockUnitOfWorkFactory = this.mockRepository.Create(); - this.mockUnitOfWorkManager = this.mockRepository.Create(); - this.mockLogger = this.mockRepository.Create>>(); - } - - private UnitOfWorkBehavior CreateUnitOfWorkBehavior() - { - return new UnitOfWorkBehavior( - this.mockUnitOfWorkFactory.Object, - this.mockUnitOfWorkManager.Object, - this.mockLogger.Object); - } - - [Test] - public async Task Handle_StateUnderTest_ExpectedBehavior() - { - // Arrange - var unitOfWorkBehavior = this.CreateUnitOfWorkBehavior(); - TRequest request = default(TRequest); - RequestHandlerDelegate next = null; - CancellationToken cancellationToken = default(global::System.Threading.CancellationToken); - - // Act - var result = await unitOfWorkBehavior.Handle( - request, - next, - cancellationToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - }*/ -} diff --git a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/ValidatorBehaviorTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/ValidatorBehaviorTests.cs deleted file mode 100644 index 7c07e44f..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/Behaviors/ValidatorBehaviorTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using FluentValidation; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR.Behaviors; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR.Tests.Behaviors -{ - /* [TestFixture] - public class ValidatorBehaviorTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock>> mockEnumerable; - private Mock>> mockLogger; - - public ValidatorBehaviorTests() : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockEnumerable = this.mockRepository.Create>>(); - this.mockLogger = this.mockRepository.Create>>(); - } - - private ValidatorBehavior CreateValidatorBehavior() - { - return new ValidatorBehavior( - this.mockEnumerable.Object, - this.mockLogger.Object); - } - - [Test] - public async Task Handle_StateUnderTest_ExpectedBehavior() - { - // Arrange - var validatorBehavior = this.CreateValidatorBehavior(); - TRequest request = default(TRequest); - RequestHandlerDelegate next = null; - CancellationToken cancellationToken = default(global::System.Threading.CancellationToken); - - // Act - var result = await validatorBehavior.Handle( - request, - next, - cancellationToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - }*/ -} diff --git a/Tests/RCommon.Mediator.MediatR.Tests/MediatrConfigurationTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/MediatrConfigurationTests.cs deleted file mode 100644 index 3a653ce2..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/MediatrConfigurationTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR; -using System; - -namespace RCommon.Mediator.MediatR.Tests -{ - [TestFixture] - public class MediatrConfigurationTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock mockServiceCollection; - - public MediatrConfigurationTests() : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockServiceCollection = this.mockRepository.Create(); - } - - private MediatRBuilder CreateMediatrConfiguration() - { - return new MediatRBuilder( - this.mockServiceCollection.Object); - } - - [Test] - public void AddMediatr_StateUnderTest_ExpectedBehavior() - { - // Arrange - var mediatrConfiguration = this.CreateMediatrConfiguration(); - Action options = null; - - // Act - var result = mediatrConfiguration.AddMediatr(x=> - { - - }); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - - [Test] - public void AddMediatr_StateUnderTest_ExpectedBehavior1() - { - // Arrange - var mediatrConfiguration = this.CreateMediatrConfiguration(); - MediatRServiceConfiguration options = null; - - // Act - var result = mediatrConfiguration.AddMediatr( - options); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - } -} diff --git a/Tests/RCommon.Mediator.MediatR.Tests/MediatrServiceTests.cs b/Tests/RCommon.Mediator.MediatR.Tests/MediatrServiceTests.cs deleted file mode 100644 index c00be9a7..00000000 --- a/Tests/RCommon.Mediator.MediatR.Tests/MediatrServiceTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -using MediatR; -using Microsoft.Extensions.DependencyInjection; -using Moq; -using NUnit.Framework; -using RCommon.Mediator.MediatR; -using System; -using System.Threading.Tasks; - -namespace RCommon.Mediator.MediatR.Tests -{ - [TestFixture] - public class MediatrServiceTests : MediatRTestBase - { - private MockRepository mockRepository; - - private Mock mockMediator; - - public MediatrServiceTests() : base() - { - var services = new ServiceCollection(); - this.InitializeRCommon(services); - } - - [SetUp] - public void SetUp() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockMediator = this.mockRepository.Create(); - } - - private MediatrService CreateService() - { - return new MediatrService( - this.mockMediator.Object); - } - - [Test] - public async Task Publish_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - object notification = null; - CancellationToken cancellation = default(global::System.Threading.CancellationToken); - - // Act - await service.Publish( - notification, - cancellation); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - - [Test] - public async Task Send_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - object notification = null; - CancellationToken cancellationToken = default(global::System.Threading.CancellationToken); - - // Act - await service.Send( - notification, - cancellationToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } - } -}