Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,37 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="ClientProxyBase" Version="2026.10.3" />
<PackageVersion Include="HealthMonitoring.Client" Version="2026.9.4.53" />
<PackageVersion Include="Shared.Results" Version="2026.10.3" />
<PackageVersion Include="ClientProxyBase" Version="2026.10.4" />
<PackageVersion Include="HealthMonitoring.Client" Version="2026.10.1" />
<PackageVersion Include="Shared.Results" Version="2026.10.4" />
<PackageVersion Include="NLog.Extensions.Logging" Version="6.2.2" />
<PackageVersion Include="MediatR" Version="14.2.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.13" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.13" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.13" />
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0" />
<PackageVersion Include="SharpCompress" Version="0.50.5" />
<PackageVersion Include="SharpCompress" Version="0.50.7" />
<PackageVersion Include="SimpleResults" Version="4.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.5.1" />
<PackageVersion Include="Shared.EventStore" Version="2026.10.3" />
<PackageVersion Include="Shared.EventStore" Version="2026.10.4" />
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="SSH.NET" Version="2026.0.0" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.13" />
<PackageVersion Include="TransactionProcessing.ApiDefaults" Version="2026.10.4" />
<PackageVersion Include="xunit.v3.mtp-v2" Version="4.0.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.12.0" />
<PackageVersion Include="Grpc.Net.Client" Version="2.84.0" />
<PackageVersion Include="Shared" Version="2026.10.3" />
<PackageVersion Include="Shared.DomainDrivenDesign" Version="2026.10.3" />
<PackageVersion Include="Shared.IntegrationTesting" Version="2026.10.3" />
<PackageVersion Include="Shared.Logger" Version="2026.10.3" />
<PackageVersion Include="Shared.Results.Web" Version="2026.10.3" />
<PackageVersion Include="Shared" Version="2026.10.4" />
<PackageVersion Include="Shared.DomainDrivenDesign" Version="2026.10.4" />
<PackageVersion Include="Shared.IntegrationTesting" Version="2026.10.4" />
<PackageVersion Include="Shared.Logger" Version="2026.10.4" />
<PackageVersion Include="Shared.Results.Web" Version="2026.10.4" />
<PackageVersion Include="Ductus.FluentDocker" Version="2.85.0" />
<PackageVersion Include="Reqnroll.Tools.MsBuild.Generation" Version="3.3.4" />
<PackageVersion Include="NUnit" Version="5.0.0" />
<PackageVersion Include="Lamar" Version="16.0.0" />
<PackageVersion Include="Imposter" Version="1.0.1" />
<PackageVersion Include="Imposter" Version="1.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.13" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.13" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.13" />
Expand All @@ -48,19 +49,13 @@
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.13" />
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="10.0.13" />
<PackageVersion Include="SimpleResults.AspNetCore" Version="4.0.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="10.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Filters" Version="10.0.1" />
<PackageVersion Include="Swashbuckle.AspNetCore.Swagger" Version="10.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerGen" Version="10.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.3.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="10.0.13" />
<PackageVersion Include="Sentry.AspNetCore" Version="6.12.1" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.3.1" />
<PackageVersion Include="Reqnroll" Version="3.3.4" />
<PackageVersion Include="Reqnroll.NUnit" Version="3.3.4" />
<PackageVersion Include="SecurityService.Client" Version="2026.9.3.198" />
<PackageVersion Include="SecurityService.IntegrationTesting.Helpers" Version="2026.9.3.198" />
<PackageVersion Include="SecurityService.Client" Version="2026.10.1" />
<PackageVersion Include="SecurityService.IntegrationTesting.Helpers" Version="2026.10.1" />
<PackageVersion Include="coverlet.collector" Version="10.1.0" />
</ItemGroup>
</Project>
25 changes: 17 additions & 8 deletions MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using System.Text;
using System.Threading.Tasks;
using Xunit;
using MessagingService.Bootstrapper;
using Shared.General;

namespace MessagingService.BusinessLogic.Tests.Mediator
{
Expand Down Expand Up @@ -40,15 +42,21 @@ public async Task Mediator_Send_RequestHandled() {
hostingEnvironment.ApplicationName.Getter().Returns("Test Application");

ServiceRegistry services = new();
Startup s = new(hostingEnvironment.Instance());
Startup.Configuration = this.SetupMemoryConfiguration();
IConfigurationRoot configuration = this.SetupMemoryConfiguration();
ConfigurationReader.Initialise(configuration);

this.AddTestRegistrations(services, hostingEnvironment.Instance());
s.ConfigureContainer(services);
//Startup.Container.AssertConfigurationIsValid(AssertMode.Full);
this.AddTestRegistrations(services, hostingEnvironment.Instance(), configuration);
services.IncludeRegistry(new MediatorRegistry());
services.IncludeRegistry(new RepositoryRegistry(configuration));
services.IncludeRegistry(new MiddlewareRegistry(configuration));
services.IncludeRegistry(new DomainServiceRegistry());
services.IncludeRegistry(new DomainEventHandlerRegistry(configuration));
services.IncludeRegistry(new MessagingProxyRegistry(configuration));
services.IncludeRegistry(new SerialiserRegistry());
Container container = new(services);

List<String> errors = new();
IMediator mediator = Startup.Container.GetService<IMediator>();
IMediator mediator = container.GetService<IMediator>();
foreach (IBaseRequest baseRequest in this.Requests) {
try {
await mediator.Send(baseRequest);
Expand Down Expand Up @@ -76,14 +84,15 @@ private IConfigurationRoot SetupMemoryConfiguration()
}

private void AddTestRegistrations(ServiceRegistry services,
IWebHostEnvironment hostingEnvironment) {
IWebHostEnvironment hostingEnvironment,
IConfiguration configuration) {
services.AddLogging();
DiagnosticListener diagnosticSource = new(hostingEnvironment.ApplicationName);
services.AddSingleton<DiagnosticSource>(diagnosticSource);
services.AddSingleton<DiagnosticListener>(diagnosticSource);
services.AddSingleton<IWebHostEnvironment>(hostingEnvironment);
services.AddSingleton<IHostEnvironment>(hostingEnvironment);
services.AddSingleton<IConfiguration>(Startup.Configuration);
services.AddSingleton(configuration);

services.OverrideServices(s => { s.AddSingleton<IMessagingDomainService, DummyMessagingDomainService>(); });
}
Expand Down
9 changes: 5 additions & 4 deletions MessagingService.DataTransferObjects/EmailAttachment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>
///
/// </summary>
/// <summary>Describes a file attached to an email.</summary>
[ExcludeFromCodeCoverage]
public class EmailAttachment
{
/// <summary>Gets or sets the attachment contents encoded as a Base64 string.</summary>
public String FileData { get; set; }

/// <summary>Gets or sets the attachment filename.</summary>
public String Filename { get; set; }

/// <summary>Gets or sets the attachment file type.</summary>
public FileType FileType { get; set; }
}
}
}
5 changes: 4 additions & 1 deletion MessagingService.DataTransferObjects/FileType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
{
using System.Diagnostics.CodeAnalysis;

/// <summary>Specifies the supported email attachment file types.</summary>
public enum FileType
{
/// <summary>No recognized file type.</summary>
None = 0,

/// <summary>Portable Document Format (PDF).</summary>
PDF
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

<PropertyGroup>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net5.0|AnyCPU'">
<DocumentationFile>D:\Projects\StuartFerguson\Messaging\MessagingService.DataTransferObjects\MessagingService.DataTransferObjects.xml</DocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 5 additions & 1 deletion MessagingService.DataTransferObjects/ResendEmailRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>Identifies an existing email message to resend.</summary>
[ExcludeFromCodeCoverage]
public class ResendEmailRequest
{
/// <summary>Gets or sets the identifier of the message to resend.</summary>
public Guid MessageId { get; set; }

/// <summary>Gets or sets the identifier of the messaging connection used for the original message.</summary>
public Guid ConnectionIdentifier { get; set; }
}
}
}
5 changes: 4 additions & 1 deletion MessagingService.DataTransferObjects/ResendSMSRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>Identifies an existing SMS message to resend.</summary>
[ExcludeFromCodeCoverage]
public class ResendSMSRequest{
/// <summary>Gets or sets the identifier of the message to resend.</summary>
public Guid MessageId{ get; set; }

/// <summary>Gets or sets the identifier of the messaging connection used for the original message.</summary>
public Guid ConnectionIdentifier{ get; set; }
}
}
}
12 changes: 11 additions & 1 deletion MessagingService.DataTransferObjects/SendEmailRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,38 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

/// <summary>Describes an email message to send.</summary>
[ExcludeFromCodeCoverage]
public class SendEmailRequest
{
/// <summary>Initializes a new request with an empty attachment collection.</summary>
public SendEmailRequest()
{
this.EmailAttachments = new List<EmailAttachment>();
}

/// <summary>Gets or sets an optional caller-supplied message identifier. The service generates an identifier when this value is omitted or null.</summary>
public Guid? MessageId { get; set; }

/// <summary>Gets or sets the email body. Its interpretation as plain text or HTML is controlled by <see cref="IsHtml"/>.</summary>
public String Body { get; set; }

/// <summary>Gets or sets the identifier of the messaging connection to use.</summary>
public Guid ConnectionIdentifier { get; set; }

/// <summary>Gets or sets the sender email address.</summary>
public String FromAddress { get; set; }

/// <summary>Gets or sets a value indicating whether <see cref="Body"/> contains HTML.</summary>
public Boolean IsHtml { get; set; }

/// <summary>Gets or sets the email subject.</summary>
public String Subject { get; set; }

/// <summary>Gets or sets the recipient email addresses.</summary>
public List<String> ToAddresses { get; set; }

/// <summary>Gets or sets attachments to include with the email. This collection defaults to empty.</summary>
public List<EmailAttachment> EmailAttachments { get; set; }
}
}
}
4 changes: 3 additions & 1 deletion MessagingService.DataTransferObjects/SendEmailResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>Contains the result identifier for a send-email request.</summary>
[ExcludeFromCodeCoverage]
public class SendEmailResponse
{
/// <summary>Gets or sets the identifier assigned to the message.</summary>
public Guid MessageId { get; set; }
}
}
}
8 changes: 7 additions & 1 deletion MessagingService.DataTransferObjects/SendSMSRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>Describes an SMS message to send.</summary>
[ExcludeFromCodeCoverage]
public class SendSMSRequest
{
/// <summary>Gets or sets the identifier of the messaging connection to use.</summary>
public Guid ConnectionIdentifier { get; set; }

/// <summary>Gets or sets the recipient phone number.</summary>
public String Destination { get; set; }

/// <summary>Gets or sets the text content of the SMS message.</summary>
public String Message { get; set; }

/// <summary>Gets or sets an optional caller-supplied message identifier. The service generates an identifier when this value is omitted or null.</summary>
public Guid? MessageId { get; set; }

/// <summary>Gets or sets the sender name or number shown to the recipient.</summary>
public String Sender { get; set; }
}
}
}
4 changes: 3 additions & 1 deletion MessagingService.DataTransferObjects/SendSMSResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>Contains the result identifier for a send-SMS request.</summary>
[ExcludeFromCodeCoverage]
public class SendSMSResponse
{
/// <summary>Gets or sets the identifier assigned to the message.</summary>
public Guid MessageId { get; set; }
}
}
}
2 changes: 1 addition & 1 deletion MessagingService.IntegrationTests/Common/GenericSteps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public async Task StartSystem()
logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName);
LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly);

DockerServices dockerServices = DockerServices.SqlServer | DockerServices.MessagingService | DockerServices.EventStore | DockerServices.SecurityService;
DockerServices dockerServices = DockerServices.SqlServer | DockerServices.MessagingService | DockerServices.KurrentDb | DockerServices.SecurityService;

this.TestingContext.DockerHelper = new();
this.TestingContext.DockerHelper.Logger = logger;
Expand Down
16 changes: 6 additions & 10 deletions MessagingService/Bootstrapper/DomainEventHandlerRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
[ExcludeFromCodeCoverage]
public class DomainEventHandlerRegistry : ServiceRegistry
{
public DomainEventHandlerRegistry()
public DomainEventHandlerRegistry(IConfiguration configuration)
{
Dictionary<String, String[]> eventHandlersConfiguration = new Dictionary<String, String[]>();

if (Startup.Configuration != null)
IConfigurationSection section = configuration.GetSection("AppSettings:EventHandlerConfiguration");
if (section.Exists())
{
IConfigurationSection section = Startup.Configuration.GetSection("AppSettings:EventHandlerConfiguration");

if (section != null)
{
Startup.Configuration.GetSection("AppSettings:EventHandlerConfiguration").Bind(eventHandlersConfiguration);
}
section.Bind(eventHandlersConfiguration);
}
this.AddSingleton<EmailDomainEventHandler>();
this.AddSingleton<SMSDomainEventHandler>();
Expand All @@ -37,8 +33,8 @@ public DomainEventHandlerRegistry()
return handler;
});

this.For<IDomainEventHandlerResolver>().Use<DomainEventHandlerResolver>().Named("Main")
this.For<IDomainEventHandlerResolver>().Use<DomainEventHandlerResolver>()
.Ctor<Dictionary<String, String[]>>().Is(eventHandlersConfiguration).Singleton();
this.AddSingleton<IDomainEventFactory<IDomainEvent>, DomainEventFactory>();
}
}
}
15 changes: 9 additions & 6 deletions MessagingService/Bootstrapper/MessagingProxyRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
[ExcludeFromCodeCoverage]
public class MessagingProxyRegistry : ServiceRegistry
{
public MessagingProxyRegistry()
private readonly IConfiguration configuration;

public MessagingProxyRegistry(IConfiguration configuration)
{
this.configuration = configuration;
this.AddHttpContextAccessor();

this.RegisterEmailProxy();
Expand All @@ -31,10 +34,10 @@ public MessagingProxyRegistry()

private void RegisterEmailProxy() {
// read the config setting
String emailProxy = ConfigurationReader.GetValue("AppSettings", "EmailProxy");
String emailProxy = this.configuration.GetValue<String>("AppSettings:EmailProxy");

if (emailProxy == "Smtp2Go") {
Smtp2GConfig config = Startup.Configuration.GetSection("AppSettings:Smtp2Go").Get<Smtp2GConfig>() ?? throw new InvalidOperationException("Smtp2Go config missing");
Smtp2GConfig config = this.configuration.GetSection("AppSettings:Smtp2Go").Get<Smtp2GConfig>() ?? throw new InvalidOperationException("Smtp2Go config missing");
this.AddSingleton(config);
this.RegisterHttpClient<IEmailServiceProxy, Smtp2GoProxy>();
}
Expand All @@ -45,15 +48,15 @@ private void RegisterEmailProxy() {

private void RegisterSMSProxy() {
// read the config setting
String smsProxy = ConfigurationReader.GetValue("AppSettings", "SMSProxy");
String smsProxy = this.configuration.GetValue<String>("AppSettings:SMSProxy");

if (smsProxy == "TheSMSWorks") {
SmsWorksConfig config = Startup.Configuration.GetSection("AppSettings:TheSmsWorks").Get<SmsWorksConfig>() ?? throw new InvalidOperationException("SmsWorks config missing");
SmsWorksConfig config = this.configuration.GetSection("AppSettings:TheSmsWorks").Get<SmsWorksConfig>() ?? throw new InvalidOperationException("SmsWorks config missing");
this.AddSingleton(config);
this.RegisterHttpClient<ISMSServiceProxy, TheSmsWorksProxy>();
}
else {
this.AddSingleton<ISMSServiceProxy, IntegrationTestSMSServiceProxy>();
}
}
}
}
Loading
Loading