Files
ReC/src/ReC.Application/DependencyInjection.cs
Developer 02 51b9c62188 Add SqlException config options and update dependencies
Added ConfigureSqlException methods to DependencyInjection for flexible SQL exception handling configuration. Updated RecApplicationTestBase to use new options. Bumped DigitalData.Core.Exceptions to v1.1.1.
2026-01-22 01:49:59 +01:00

141 lines
4.8 KiB
C#

using FluentValidation;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ReC.Application.Common.Behaviors;
using ReC.Application.Common.Constants;
using ReC.Application.Common.Options;
using ReC.Application.Common.Procedures;
using System.Reflection;
namespace ReC.Application;
public static class DependencyInjection
{
public static IServiceCollection AddRecServices(this IServiceCollection services, Action<ConfigurationOptions> options)
{
var configOpt = new ConfigurationOptions();
options.Invoke(configOpt);
configOpt.EnsureRequiredServices();
configOpt.ApplyConfigurations(services);
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddAutoMapper(cfg =>
{
cfg.AddMaps(Assembly.GetExecutingAssembly());
cfg.LicenseKey = configOpt.LuckyPennySoftwareLicenseKey;
});
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
cfg.AddOpenBehaviors([typeof(BodyQueryBehavior<,>), typeof(HeaderQueryBehavior<,>)]);
cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
cfg.LicenseKey = configOpt.LuckyPennySoftwareLicenseKey;
});
services.AddHttpClient(Http.ClientName)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
UseDefaultCredentials = false
});
return services;
}
public class ConfigurationOptions
{
#region Required Services
private readonly Dictionary<string, bool> _requiredServices = new()
{
{ nameof(ConfigureRecActions), false },
{ nameof(LuckyPennySoftwareLicenseKey), false }
};
internal void EnsureRequiredServices()
{
var missingServices = _requiredServices
.Where(kvp => !kvp.Value)
.Select(kvp => kvp.Key.Replace("Configure", string.Empty));
if (missingServices.Any())
throw new InvalidOperationException($"The following required services were not configured: {string.Join(", ", missingServices)}");
}
#endregion Required Services
#region Configuration
private readonly Queue<Action<IServiceCollection>> _configActions = new();
internal void ApplyConfigurations(IServiceCollection services)
{
while (_configActions.Count > 0)
{
var action = _configActions.Dequeue();
action(services);
}
}
#endregion Configuration
#region LuckyPennySoftwareLicenseKey
private string? _luckyPennySoftwareLicenseKey;
public string? LuckyPennySoftwareLicenseKey
{
get => _luckyPennySoftwareLicenseKey;
set
{
_luckyPennySoftwareLicenseKey = value;
if (value is not null)
_requiredServices[nameof(LuckyPennySoftwareLicenseKey)] = true;
}
}
#endregion LuckyPennySoftwareLicenseKey
#region ConfigureRecActions
public ConfigurationOptions ConfigureRecActions(Action<RecActionOptions> configure)
{
_configActions.Enqueue(services => services.Configure(configure));
if(_requiredServices[nameof(ConfigureRecActions)])
throw new InvalidOperationException("RecActionOptions have already been configured.");
_requiredServices[nameof(ConfigureRecActions)] = true;
return this;
}
public ConfigurationOptions ConfigureRecActions(IConfiguration configuration)
{
_configActions.Enqueue(services => services.Configure<RecActionOptions>(configuration));
if (_requiredServices[nameof(ConfigureRecActions)])
throw new InvalidOperationException("RecActionOptions have already been configured.");
_requiredServices[nameof(ConfigureRecActions)] = true;
return this;
}
#endregion ConfigureRecActions
#region ConfigureSqlException
public ConfigurationOptions ConfigureSqlException(Action<SqlExceptionOptions> configure)
{
_configActions.Enqueue(services => services.Configure(configure));
return this;
}
public ConfigurationOptions ConfigureSqlException(IConfiguration configuration)
{
_configActions.Enqueue(services =>
{
services.Configure<SqlExceptionOptions>(configuration);
});
return this;
}
#endregion ConfigureSqlException
}
}