From 7f05107c1db5fbedba889af484604913e3fedb5b Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 1 Jun 2026 07:32:42 -0400 Subject: [PATCH] feat(audit): AddZbAudit DI extension with safe defaults TryAdd registers NullAuditRedactor + NoOpAuditWriter so consumer registrations win; symmetric override tests for both writer and redactor. --- .../AuditServiceCollectionExtensions.cs | 21 ++++++++++++ .../AuditServiceCollectionExtensionsTests.cs | 32 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 ZB.MOM.WW.Audit/src/ZB.MOM.WW.Audit/AuditServiceCollectionExtensions.cs create mode 100644 ZB.MOM.WW.Audit/tests/ZB.MOM.WW.Audit.Tests/AuditServiceCollectionExtensionsTests.cs diff --git a/ZB.MOM.WW.Audit/src/ZB.MOM.WW.Audit/AuditServiceCollectionExtensions.cs b/ZB.MOM.WW.Audit/src/ZB.MOM.WW.Audit/AuditServiceCollectionExtensions.cs new file mode 100644 index 0000000..52bc006 --- /dev/null +++ b/ZB.MOM.WW.Audit/src/ZB.MOM.WW.Audit/AuditServiceCollectionExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace ZB.MOM.WW.Audit; + +/// DI helpers for ZB.MOM.WW.Audit. +public static class AuditServiceCollectionExtensions +{ + /// + /// Registers safe defaults — and — + /// using TryAdd so a consumer that has already registered a real writer/redactor wins. Consumers + /// compose / around their own sink. + /// + public static IServiceCollection AddZbAudit(this IServiceCollection services) + { + ArgumentNullException.ThrowIfNull(services); + services.TryAddSingleton(NullAuditRedactor.Instance); + services.TryAddSingleton(NoOpAuditWriter.Instance); + return services; + } +} diff --git a/ZB.MOM.WW.Audit/tests/ZB.MOM.WW.Audit.Tests/AuditServiceCollectionExtensionsTests.cs b/ZB.MOM.WW.Audit/tests/ZB.MOM.WW.Audit.Tests/AuditServiceCollectionExtensionsTests.cs new file mode 100644 index 0000000..d733786 --- /dev/null +++ b/ZB.MOM.WW.Audit/tests/ZB.MOM.WW.Audit.Tests/AuditServiceCollectionExtensionsTests.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace ZB.MOM.WW.Audit.Tests; + +public class AuditServiceCollectionExtensionsTests +{ + [Fact] + public void Registers_null_redactor_and_noop_writer_by_default() + { + var sp = new ServiceCollection().AddZbAudit().BuildServiceProvider(); + Assert.IsType(sp.GetRequiredService()); + Assert.IsType(sp.GetRequiredService()); + } + + [Fact] + public void Does_not_override_a_preregistered_writer() + { + var services = new ServiceCollection(); + services.AddSingleton(new CompositeAuditWriter(System.Array.Empty())); + var sp = services.AddZbAudit().BuildServiceProvider(); + Assert.IsType(sp.GetRequiredService()); + } + + [Fact] + public void Does_not_override_a_preregistered_redactor() + { + var services = new ServiceCollection(); + services.AddSingleton(new TruncatingAuditRedactor()); + var sp = services.AddZbAudit().BuildServiceProvider(); + Assert.IsType(sp.GetRequiredService()); + } +}