diff --git a/EnvelopeGenerator.DependencyInjection/DependencyInjection.cs b/EnvelopeGenerator.DependencyInjection/DependencyInjection.cs
index cebe6df9..8bbbc853 100644
--- a/EnvelopeGenerator.DependencyInjection/DependencyInjection.cs
+++ b/EnvelopeGenerator.DependencyInjection/DependencyInjection.cs
@@ -4,12 +4,59 @@ using EnvelopeGenerator.Application;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
using EnvelopeGenerator.Application.Services;
using EnvelopeGenerator.Infrastructure;
+using DigitalData.EmailProfilerDispatcher;
+using DigitalData.UserManager.DependencyInjection;
namespace EnvelopeGenerator.DependencyInjection;
+///
+/// Controls which optional services are registered by .
+/// All flags default to true. Set a flag to false if the consuming project
+/// already registers that service itself or simply does not need it.
+///
+public sealed class EnvelopeGeneratorOptions
+{
+ /// Calls AddHttpContextAccessor(). Default: true.
+ public bool AddHttpContextAccessor { get; set; } = true;
+
+ ///
+ /// Calls AddDistributedSqlServerCache() with the supplied .
+ /// Requires to be configured. Default: true.
+ ///
+ public bool AddDistributedSqlServerCache { get; set; } = true;
+
+ ///
+ /// Options for the distributed SQL Server cache.
+ /// Required when is true.
+ ///
+ public SqlCacheOptions? SqlCacheOptions { get; set; }
+
+ /// Calls AddDispatcher<TDbContext>(). Default: true.
+ public bool AddDispatcher { get; set; } = true;
+
+ /// Calls AddMemoryCache(). Default: true.
+ public bool AddMemoryCache { get; set; } = true;
+
+ /// Calls AddUserManager<TDbContext>(). Default: true.
+ public bool AddUserManager { get; set; } = true;
+}
+
+/// Options for AddDistributedSqlServerCache.
+public sealed class SqlCacheOptions
+{
+ /// SQL Server connection string.
+ public string ConnectionString { get; set; } = string.Empty;
+
+ /// Schema name. Default: dbo.
+ public string SchemaName { get; set; } = "dbo";
+
+ /// Table name. Default: TBDD_CACHE.
+ public string TableName { get; set; } = "TBDD_CACHE";
+}
+
///
/// Extension methods for registering EnvelopeGenerator services into an .
-/// Use as the single entry-point for projects that need both the
+/// Use as the single entry-point for projects that need both the
/// application layer (MediatR, AutoMapper, CRUD services, configuration sections) and the infrastructure
/// layer (repositories, DbContext, SQL executors).
/// For projects that do not need a database (e.g. lightweight API gateways or unit-test hosts), use
@@ -18,61 +65,56 @@ namespace EnvelopeGenerator.DependencyInjection;
public static class DependencyInjection
{
///
- /// Registers the full EnvelopeGenerator stack – application and infrastructure services – into
- /// the provided .
- ///
- /// Internally this calls AddEnvelopeGeneratorServices (application layer) and
- /// AddEnvelopeGeneratorInfrastructureServices (infrastructure layer).
- /// A and / or DbTriggerParams must be
- /// configured through ; without it no database connection will
- /// be established at runtime.
- ///
+ /// Registers the full EnvelopeGenerator stack using as the DbContext type.
///
- /// Service collection to register services into.
- ///
- /// Application configuration. Used to bind DispatcherParams, MailParams,
- /// AuthenticatorParams, TotpSmsParams, GtxMessagingParams and other
- /// application-level option sections.
- ///
- ///
- /// Optional callback to configure the infrastructure layer registration.
- /// Typical usage:
- ///
- /// services.AddEnvelopeGenerator(config, opt =>
- /// {
- /// opt.AddDbContext(o => o.UseSqlServer(connectionString));
- /// opt.AddDbTriggerParams(config);
- /// });
- ///
- ///
- /// The updated .
-#pragma warning disable CS0618 // AddEnvelopeGeneratorServices / AddEnvelopeGeneratorInfrastructureServices are intentionally wrapped here
public static IServiceCollection AddEnvelopeGenerator(
this IServiceCollection services,
IConfiguration configuration,
- Action? infrastructureOptions = null)
+ Action? infrastructureOptions = null,
+ Action? options = null)
{
+ var opt = new EnvelopeGeneratorOptions();
+ options?.Invoke(opt);
+
+#pragma warning disable CS0618
// Application layer: CRUD services, MediatR, AutoMapper, configuration sections.
services.AddEnvelopeGeneratorServices(configuration);
// Infrastructure layer: repositories, DbContext, Dapper type maps, SQL executors.
- services.AddEnvelopeGeneratorInfrastructureServices(opt =>
+ services.AddEnvelopeGeneratorInfrastructureServices(cfg =>
{
- infrastructureOptions?.Invoke(opt);
+ infrastructureOptions?.Invoke(cfg);
});
+#pragma warning restore CS0618
+
+ if (opt.AddHttpContextAccessor)
+ services.AddHttpContextAccessor();
+
+ if (opt.AddDistributedSqlServerCache && opt.SqlCacheOptions is { } cacheOpts)
+ services.AddDistributedSqlServerCache(o =>
+ {
+ o.ConnectionString = cacheOpts.ConnectionString;
+ o.SchemaName = cacheOpts.SchemaName;
+ o.TableName = cacheOpts.TableName;
+ });
+
+ if (opt.AddDispatcher)
+ services.AddDispatcher();
+
+ if (opt.AddMemoryCache)
+ services.AddMemoryCache();
+
+#pragma warning disable CS0618
+ if (opt.AddUserManager)
+ services.AddUserManager();
+#pragma warning restore CS0618
return services;
}
-#pragma warning restore CS0618
///
/// Registers only the application layer services (MediatR handlers, AutoMapper profiles,
/// CRUD services, configuration sections) without any infrastructure / database dependencies.
- ///
- /// Useful for projects that already manage their own DbContext or do not require direct database
- /// access, such as lightweight API gateways, console tools or unit/integration test hosts that
- /// use an in-memory database configured elsewhere.
- ///
///
/// Service collection to register services into.
/// Application configuration used to bind application-level option sections.
@@ -90,11 +132,6 @@ public static class DependencyInjection
///
/// Registers as the scoped
/// implementation.
- ///
- /// Call this in addition to when the consuming project needs to
- /// send envelope e-mails directly (e.g. a Worker Service or the Web project). Projects that rely
- /// purely on MediatR commands to trigger mail delivery do not need to call this.
- ///
///
/// Service collection to register services into.
/// The updated .
diff --git a/EnvelopeGenerator.DependencyInjection/EnvelopeGenerator.DependencyInjection.csproj b/EnvelopeGenerator.DependencyInjection/EnvelopeGenerator.DependencyInjection.csproj
index e1df3bc2..96e2398e 100644
--- a/EnvelopeGenerator.DependencyInjection/EnvelopeGenerator.DependencyInjection.csproj
+++ b/EnvelopeGenerator.DependencyInjection/EnvelopeGenerator.DependencyInjection.csproj
@@ -25,9 +25,28 @@
false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs
index c4b2b521..f25a9888 100644
--- a/EnvelopeGenerator.Web/Program.cs
+++ b/EnvelopeGenerator.Web/Program.cs
@@ -12,7 +12,6 @@ using DigitalData.EmailProfilerDispatcher;
using EnvelopeGenerator.Infrastructure;
using EnvelopeGenerator.Web.Sanitizers;
using EnvelopeGenerator.Web.Models.Annotation;
-using DigitalData.UserManager.DependencyInjection;
using EnvelopeGenerator.Web.Middleware;
using EnvelopeGenerator.DependencyInjection;
using EnvelopeGenerator.Web;
@@ -55,8 +54,6 @@ try
});
});
- builder.Services.AddHttpContextAccessor();
-
builder.ConfigureBySection();
// Add controllers and razor views
@@ -93,26 +90,29 @@ try
var connStr = config.GetConnectionString(cnnStrName)
?? throw new InvalidOperationException($"Connection string '{cnnStrName}' is missing in the application configuration.");
- builder.Services.AddDistributedSqlServerCache(options =>
- {
- options.ConnectionString = connStr;
- options.SchemaName = "dbo";
- options.TableName = "TBDD_CACHE";
- });
-
// Add envelope generator services
- builder.Services.AddEnvelopeGenerator(config, opt =>
- {
- opt.AddDbTriggerParams(config);
- opt.AddDbContext((provider, options) =>
+ builder.Services.AddEnvelopeGenerator(config,
+ infrastructureOptions: opt =>
{
- var logger = provider.GetRequiredService>();
- options.UseSqlServer(connStr)
- .LogTo(log => logger.LogInformation("{log}", log), Microsoft.Extensions.Logging.LogLevel.Trace)
- .EnableSensitiveDataLogging()
- .EnableDetailedErrors();
+ opt.AddDbTriggerParams(config);
+ opt.AddDbContext((provider, options) =>
+ {
+ var logger = provider.GetRequiredService>();
+ options.UseSqlServer(connStr)
+ .LogTo(log => logger.LogInformation("{log}", log), Microsoft.Extensions.Logging.LogLevel.Trace)
+ .EnableSensitiveDataLogging()
+ .EnableDetailedErrors();
+ });
+ },
+ options: opt =>
+ {
+ opt.SqlCacheOptions = new()
+ {
+ ConnectionString = connStr,
+ SchemaName = "dbo",
+ TableName = "TBDD_CACHE"
+ };
});
- });
builder.Services.Configure(options =>
{
@@ -162,18 +162,10 @@ try
// Register mail services
builder.Services.AddEnvelopeMailService();
- builder.Services.AddDispatcher();
-
- builder.Services.AddMemoryCache();
-
builder.ConfigureBySection();
builder.ConfigureBySection();
-#pragma warning disable CS0618 // Type or member is obsolete
- builder.Services.AddUserManager();
-#pragma warning restore CS0618 // Type or member is obsolete
-
var app = builder.Build();
app.UseMiddleware();