Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.
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
20 changes: 20 additions & 0 deletions src/ServiceLayer.Common/Data/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ServiceLayer.Common;

namespace ServiceLayer.Data;

internal static class ServiceCollectionExtensions
{
internal static IServiceCollection AddDbContext(this IServiceCollection services)
{
services.AddDbContext<ServiceLayerDbContext>(options =>
{
var connectionString = EnvironmentVariables.GetRequired("DatabaseConnectionString");

options.UseSqlServer(connectionString);
});

return services;
}
}
12 changes: 12 additions & 0 deletions src/ServiceLayer.Common/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.Extensions.DependencyInjection;
using ServiceLayer.Data;

namespace ServiceLayer;

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCommonServices(this IServiceCollection services)
{
return services.AddDbContext();
}
}
18 changes: 18 additions & 0 deletions src/ServiceLayer.Mesh/Configuration/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.Extensions.DependencyInjection;

namespace ServiceLayer.Mesh.Configuration;

internal static class ServiceCollectionExtensions
{
internal static IServiceCollection AddApplicationConfiguration(this IServiceCollection services)
{
services.AddTransient<IFileDiscoveryFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileExtractQueueClientConfiguration, AppConfiguration>();
services.AddTransient<IFileTransformQueueClientConfiguration, AppConfiguration>();
services.AddTransient<IMeshHandshakeFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileRetryFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileTransformFunctionConfiguration, AppConfiguration>();

return services;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@

namespace ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents;

public static class ServiceCollectionExtensions
internal static class ServiceCollectionExtensions
{
public static IServiceCollection ConfigureNbssAppointmentEvents(this IServiceCollection services)
internal static IServiceCollection AddNbssAppointmentEventServices(this IServiceCollection services)
{
services.AddTransient<IFileTransformer, FileTransformer>();
services.AddTransient<IFileParser, FileParser>();
services.AddTransient<IStagingPersister, StagingPersister>();
services.AddSingleton<IValidationRunner, ValidationRunner>();
services.RegisterValidators();
services.AddValidators();

return services;
}

private static IServiceCollection RegisterValidators(this IServiceCollection services)
private static IServiceCollection AddValidators(this IServiceCollection services)
{
foreach (var recordValidator in ValidatorRegistry.GetAllRecordValidators())
{
Expand Down
35 changes: 35 additions & 0 deletions src/ServiceLayer.Mesh/Messaging/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Azure.Identity;
using Azure.Storage.Queues;
using Microsoft.Extensions.DependencyInjection;
using ServiceLayer.Common;

namespace ServiceLayer.Mesh.Messaging;

internal static class ServiceCollectionExtensions
{
internal static IServiceCollection AddMessagingServices(this IServiceCollection services, bool isLocalEnvironment)
{
var queueClientOptions = new QueueClientOptions
{
MessageEncoding = QueueMessageEncoding.Base64
};

// Register QueueClients as singletons
services.AddSingleton(_ =>
{
if (isLocalEnvironment)
{
var connectionString = EnvironmentVariables.GetRequired("AzureWebJobsStorage");
return new QueueServiceClient(connectionString, queueClientOptions);
}

var meshStorageAccountUrl = EnvironmentVariables.GetRequired("MeshStorageAccountUrl");
return new QueueServiceClient(new Uri(meshStorageAccountUrl), new ManagedIdentityCredential(), queueClientOptions);
});

services.AddSingleton<IFileExtractQueueClient, FileExtractQueueClient>();
services.AddSingleton<IFileTransformQueueClient, FileTransformQueueClient>();

return services;
}
}
78 changes: 19 additions & 59 deletions src/ServiceLayer.Mesh/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Azure.Storage.Queues;
using Azure.Identity;
using Microsoft.EntityFrameworkCore;
using NHS.MESH.Client;
using Azure.Storage.Blobs;
using ServiceLayer;
using ServiceLayer.Mesh.Configuration;
using ServiceLayer.Mesh.Messaging;
using ServiceLayer.Data;
using ServiceLayer.Mesh.Storage;
using ServiceLayer.Common;
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents;
Expand All @@ -19,63 +15,15 @@
var environment = EnvironmentVariables.GetRequired("ASPNETCORE_ENVIRONMENT");
var isLocalEnvironment = environment == "Development";

// MESH Client config
services
.AddMeshClient(_ => _.MeshApiBaseUrl = EnvironmentVariables.GetRequired("MeshApiBaseUrl"))
.AddMailbox(EnvironmentVariables.GetRequired("NbssMailboxId"), new NHS.MESH.Client.Configuration.MailboxConfiguration
{
Password = EnvironmentVariables.GetRequired("MeshPassword"),
SharedKey = EnvironmentVariables.GetRequired("MeshSharedKey"),
}).Build();
ConfigureMeshClient(services);

// EF Core DbContext
services.AddDbContext<ServiceLayerDbContext>(options =>
{
var connectionString = EnvironmentVariables.GetRequired("DatabaseConnectionString");
if (string.IsNullOrEmpty(connectionString))
throw new InvalidOperationException("The connection string has not been initialized.");

options.UseSqlServer(connectionString);
});

var queueClientOptions = new QueueClientOptions
{
MessageEncoding = QueueMessageEncoding.Base64
};

// Register QueueClients as singletons
services.AddSingleton(provider =>
{
if (isLocalEnvironment)
{
var connectionString = EnvironmentVariables.GetRequired("AzureWebJobsStorage");
return new QueueServiceClient(connectionString, queueClientOptions);
}

var meshStorageAccountUrl = EnvironmentVariables.GetRequired("MeshStorageAccountUrl");
return new QueueServiceClient(new Uri(meshStorageAccountUrl), new DefaultAzureCredential(), queueClientOptions);
});
services.AddCommonServices();

services.AddSingleton<IFileExtractQueueClient, FileExtractQueueClient>();
services.AddSingleton<IFileTransformQueueClient, FileTransformQueueClient>();
services.AddMessagingServices(isLocalEnvironment);
services.AddStorageServices(isLocalEnvironment);

services.AddSingleton(provider =>
{
return new BlobContainerClient(
EnvironmentVariables.GetRequired("AzureWebJobsStorage"),
EnvironmentVariables.GetRequired("BlobContainerName"));
});

services.AddSingleton<IMeshFilesBlobStore, MeshFilesBlobStore>();

services.AddTransient<IFileDiscoveryFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileExtractQueueClientConfiguration, AppConfiguration>();
services.AddTransient<IFileTransformQueueClientConfiguration, AppConfiguration>();
services.AddTransient<IMeshHandshakeFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileRetryFunctionConfiguration, AppConfiguration>();
services.AddTransient<IFileTransformFunctionConfiguration, AppConfiguration>();

services.ConfigureNbssAppointmentEvents();
services.AddApplicationConfiguration();
services.AddNbssAppointmentEventServices();
});


Expand All @@ -86,3 +34,15 @@

var app = host.Build();
await app.RunAsync();
return;

void ConfigureMeshClient(IServiceCollection services)
{
services
.AddMeshClient(_ => _.MeshApiBaseUrl = EnvironmentVariables.GetRequired("MeshApiBaseUrl"))
.AddMailbox(EnvironmentVariables.GetRequired("NbssMailboxId"), new NHS.MESH.Client.Configuration.MailboxConfiguration
{
Password = EnvironmentVariables.GetRequired("MeshPassword"),
SharedKey = EnvironmentVariables.GetRequired("MeshSharedKey"),
}).Build();
}
31 changes: 31 additions & 0 deletions src/ServiceLayer.Mesh/Storage/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Azure.Identity;
using Azure.Storage.Blobs;
using Microsoft.Extensions.DependencyInjection;
using ServiceLayer.Common;

namespace ServiceLayer.Mesh.Storage;

internal static class ServiceCollectionExtensions
{
internal static IServiceCollection AddStorageServices(this IServiceCollection services, bool isLocalEnvironment)
{
services.AddSingleton(_ =>
{
var containerName = EnvironmentVariables.GetRequired("BlobContainerName");

if (isLocalEnvironment)
{
return new BlobContainerClient(EnvironmentVariables.GetRequired("AzureWebJobsStorage"),containerName);
}

var meshStorageAccountUrl = EnvironmentVariables.GetRequired("MeshStorageAccountUrl");

var serviceClient = new BlobServiceClient(new Uri(meshStorageAccountUrl), new ManagedIdentityCredential());
return serviceClient.GetBlobContainerClient(containerName);
});

services.AddSingleton<IMeshFilesBlobStore, MeshFilesBlobStore>();

return services;
}
}
Loading