refactor(application): introduce MessagingServiceApplicationConfiguration builder
Replace the implicit IConfiguration-based DI registration with an explicit
builder that validates required steps at startup.
- Add MessagingServiceApplicationConfiguration with mandatory steps:
SetLuckyPennySoftLicenseKey(), ConfigureEmailAccounts() / PublishOnly()
- EnsureConfigured() throws at registration time if either step is missing,
surfacing misconfiguration before the app starts
- Keep the IConfiguration convenience overload as a thin wrapper over the
builder for backward-compatible call sites
- Move DependencyInjection.cs into a DependencyInjection/ subfolder alongside
the new configuration class
This commit is contained in:
@@ -1,46 +1,51 @@
|
|||||||
#if NET
|
#if NET
|
||||||
using DigitalData.MessagingService.Application.Common.Options;
|
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace DigitalData.MessagingService.Application;
|
namespace DigitalData.MessagingService.Application.DependencyInjection;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dependency injection configuration for Application layer.
|
/// Dependency injection configuration for Application layer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddMessagingServiceApplication(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddMessagingServiceApplication(this IServiceCollection services, Action<MessagingServiceApplicationConfiguration> configure)
|
||||||
{
|
{
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
// Read LuckyPennySoft license key from appsettings.json
|
var configuration = new MessagingServiceApplicationConfiguration(services);
|
||||||
var licenseKey = configuration.GetValue<string>("LuckyPennySoftLicenseKey")
|
configure(configuration);
|
||||||
?? throw new InvalidOperationException("LuckyPennySoftLicenseKey not found in configuration");
|
configuration.EnsureConfigured();
|
||||||
|
|
||||||
// MediatR - Register all handlers
|
// MediatR - Register all handlers
|
||||||
services.AddMediatR(config =>
|
services.AddMediatR(config =>
|
||||||
{
|
{
|
||||||
config.LicenseKey = licenseKey;
|
config.LicenseKey = configuration.LuckyPennySoftLicenseKey;
|
||||||
config.RegisterServicesFromAssembly(assembly);
|
config.RegisterServicesFromAssembly(assembly);
|
||||||
});
|
});
|
||||||
|
|
||||||
// AutoMapper - Use built-in DI extension (AutoMapper 16.2.0+)
|
// AutoMapper - Use built-in DI extension (AutoMapper 16.2.0+)
|
||||||
services.AddAutoMapper(config =>
|
services.AddAutoMapper(config =>
|
||||||
{
|
{
|
||||||
config.LicenseKey = licenseKey;
|
config.LicenseKey = configuration.LuckyPennySoftLicenseKey;
|
||||||
config.AddMaps(assembly);
|
config.AddMaps(assembly);
|
||||||
});
|
});
|
||||||
|
|
||||||
// FluentValidation - Register all validators
|
// FluentValidation - Register all validators
|
||||||
services.AddValidatorsFromAssembly(assembly);
|
services.AddValidatorsFromAssembly(assembly);
|
||||||
|
|
||||||
// Register EmailAccounts configuration (IOptions<EmailAccountsOptions>)
|
|
||||||
services.Configure<EmailAccountsOptions>(configuration.GetSection(EmailAccountsOptions.SectionName));
|
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddMessagingServiceApplication(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
return services.AddMessagingServiceApplication(cfg =>
|
||||||
|
{
|
||||||
|
cfg.SetLuckyPennySoftLicenseKey(configuration);
|
||||||
|
cfg.ConfigureEmailAccounts(configuration);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#if NET
|
||||||
|
using DigitalData.MessagingService.Application.Common.Options;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace DigitalData.MessagingService.Application.DependencyInjection;
|
||||||
|
|
||||||
|
public partial class MessagingServiceApplicationConfiguration
|
||||||
|
{
|
||||||
|
private IServiceCollection Services { get; }
|
||||||
|
|
||||||
|
private (bool LuckyPennySoftLicenseKey, bool EmailAccounts) _configured = (LuckyPennySoftLicenseKey: false, EmailAccounts: false);
|
||||||
|
|
||||||
|
internal MessagingServiceApplicationConfiguration(IServiceCollection services)
|
||||||
|
{
|
||||||
|
Services = services;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void EnsureConfigured()
|
||||||
|
{
|
||||||
|
if (!_configured.LuckyPennySoftLicenseKey)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("LuckyPennySoftLicenseKey is not configured. Please call SetLuckyPennySoftLicenseKey() or SetLuckyPennySoftLicenseKey(IConfiguration) in DI configuration.");
|
||||||
|
}
|
||||||
|
if (!_configured.EmailAccounts)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("EmailAccountsOptions is not configured. Please call ConfigureEmailAccountsOptions() or ConfigureEmailAccounts(IConfiguration) in DI configuration.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region LuckyPennySoftLicenseKey
|
||||||
|
internal string? LuckyPennySoftLicenseKey { get; set; } = null;
|
||||||
|
|
||||||
|
public MessagingServiceApplicationConfiguration SetLuckyPennySoftLicenseKey(string licenseKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(licenseKey))
|
||||||
|
throw new InvalidOperationException("LuckyPennySoftLicenseKey is not configured. Please call SetLuckyPennySoftLicenseKey() or SetLuckyPennySoftLicenseKey(IConfiguration) in DI configuration.");
|
||||||
|
|
||||||
|
LuckyPennySoftLicenseKey = licenseKey;
|
||||||
|
_configured.LuckyPennySoftLicenseKey = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessagingServiceApplicationConfiguration SetLuckyPennySoftLicenseKey(IConfiguration configuration, string key = "LuckyPennySoftLicenseKey")
|
||||||
|
{
|
||||||
|
return SetLuckyPennySoftLicenseKey(configuration.GetValue<string>(key) ?? string.Empty);
|
||||||
|
}
|
||||||
|
#endregion LuckyPennySoftLicenseKey
|
||||||
|
|
||||||
|
#region EmailAccountsOptions
|
||||||
|
/// <summary>
|
||||||
|
/// Ignores whether EmailAccountsOptions is configured or not. Use this method if you just want to publish messages to the messaging service; not to send
|
||||||
|
/// emails. If you want to consume the messaging service to send emails, you must configure EmailAccountsOptions using ConfigureEmailAccountsOptions() or
|
||||||
|
/// ConfigureEmailAccounts(IConfiguration).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public MessagingServiceApplicationConfiguration PublishOnly()
|
||||||
|
{
|
||||||
|
_configured.EmailAccounts = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessagingServiceApplicationConfiguration ConfigureEmailAccountsOptions(Action<EmailAccountsOptions> configureOptions)
|
||||||
|
{
|
||||||
|
Services.Configure(configureOptions);
|
||||||
|
_configured.EmailAccounts = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessagingServiceApplicationConfiguration ConfigureEmailAccounts(IConfiguration configuration, string sectionName = EmailAccountsOptions.SectionName)
|
||||||
|
{
|
||||||
|
Services.Configure<EmailAccountsOptions>(configuration.GetSection(sectionName));
|
||||||
|
_configured.EmailAccounts = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
#endregion EmailAccountsOptions
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user