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());
+ }
+}