diff --git a/Directory.Packages.props b/Directory.Packages.props index 2f712aad..0ba8e55f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,20 +4,23 @@ 5.9.0 5.9.0 - 1.68.4 - 1.0.0-prerelease.44 - 1.0.0-prerelease.2 - 2.0.0-prerelease.9 + 1.68.17 + 1.0.0-prerelease.49 + 1.0.0-prerelease.5 + 2.0.0-prerelease.20 + 5.0.0-prerelease.14 + 1.0.0-prerelease.36 + 13.5.3.4 4.15.0 0.14.0 10.0.12 13.5.4 - 1.18.0 + 1.19.0 10.10.0 - + @@ -34,13 +37,13 @@ - + - + diff --git a/Justfile b/Justfile index 47ac5f44..2de6d9b2 100644 --- a/Justfile +++ b/Justfile @@ -2,7 +2,7 @@ set quiet # Variables root_folder := "./src" -test_root := root_folder + "/tests" +# test_root := root_folder + "/tests" solution_file := root_folder + "/EventSourcing.slnx" @@ -66,6 +66,13 @@ pipeline-tests *args: echo "Running tests pipeline..." "{{ pipeline_tool }}" --Build:RunTests=true --Release:Mode=None {{ args }} +# Run the pipeline through pack + validate (restore, build, lint, tests, pack, validate pack contents) without publishing/releasing +[group('Pipeline')] +pipeline-pack-validate *args: + just ensure-pipeline-tool + echo "Running pack + validate pipeline..." + "{{ pipeline_tool }}" --Build:RunPack=true --Build:ValidatePack=true --Release:Mode=None {{ args }} + # Open the solution in Visual Studio/ Registered application [group('Utilities')] vs: diff --git a/global.json b/global.json index 6848cdda..8340158a 100644 --- a/global.json +++ b/global.json @@ -3,7 +3,7 @@ "allowPrerelease": false }, "msbuild-sdks": { - "Purview.BuildSdk": "1.0.0-prerelease.57" + "Purview.BuildSdk": "1.0.0-prerelease.58" }, "test": { "runner": "Microsoft.Testing.Platform" diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index eef8c9e1..00000000 --- a/package-lock.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "purview-event-sourcing", - "version": "2.0.0-prerelease.34", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "purview-event-sourcing", - "version": "2.0.0-prerelease.34" - } - } -} diff --git a/package.json b/package.json index 88f14100..307a5f55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "purview-event-sourcing", - "version": "2.0.0-prerelease.35", + "version": "2.0.0-prerelease.36", "license": "MIT", "author": { "name": "Kieron Lanning", diff --git a/purview-build.json b/purview-build.json index cc012a78..6ee8eb64 100644 --- a/purview-build.json +++ b/purview-build.json @@ -11,84 +11,142 @@ "RequireSymbolFiles": true, "RequiredContent": { "purview.eventsourcing": [ - "README.md", - "purview-logo-light.png", - "buildTransitive/Purview.EventSourcing.targets", + ".agents/**/*", + "analyzers/dotnet/cs/Purview.EventSourcing.SourceGenerator.CodeFixes.dll", "analyzers/dotnet/cs/Purview.EventSourcing.SourceGenerator.dll", - "analyzers/dotnet/cs/Purview.EventSourcing.SourceGenerator.CodeFixes.dll" - ], - "purview.eventsourcing.sqlserver": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.SqlServer.dll", - "analyzers/dotnet/cs/Purview.EventSourcing.EntityFrameworkCore.SourceGenerator.dll" - ], - "purview.eventsourcing.postgres": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Postgres.dll", - "analyzers/dotnet/cs/Purview.EventSourcing.EntityFrameworkCore.SourceGenerator.dll" - ], - "purview.eventsourcing.azurestorage": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.AzureStorage.dll" - ], - "purview.eventsourcing.mongodb": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.MongoDB.dll" - ], - "purview.eventsourcing.cosmosdb": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.CosmosDb.dll" - ], - "purview.eventsourcing.inmemory": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.InMemory.dll" - ], - "purview.eventsourcing.validation.fluentvalidation": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Validation.FluentValidation.dll" - ], - "purview.eventsourcing.validation.zodsharp": [ - "README.md", - "buildTransitive/Purview.EventSourcing.Validation.ZodSharp.targets" + "buildTransitive/Purview.EventSourcing.targets", + "lib/$(TFM)/Purview.EventSourcing.dll", + "lib/$(TFM)/Purview.EventSourcing.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.abstractions": [ + "lib/$(TFM)/Purview.EventSourcing.Admin.Abstractions.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.Abstractions.xml", "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.Abstractions.dll" + "purview-logo-light.png" ], "purview.eventsourcing.admin.api": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.API.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.API.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.API.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.azurestorage": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.AzureStorage.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.AzureStorage.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.AzureStorage.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.client": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.Client.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.Client.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.Client.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.mongodb": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.MongoDB.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.MongoDB.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.MongoDB.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.Admin.MongoDB.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.postgres": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.Postgres.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.Postgres.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.Postgres.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.Admin.Postgres.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.security": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.Security.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.Security.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.Security.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.site": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.Site.dll" + "content/**/*", + "contentFiles/**/*", + "lib/*/Purview.EventSourcing.Admin.Site.dll", + "lib/*/Purview.EventSourcing.Admin.Site.xml", + "purview-logo-light.png", + "README.md" ], "purview.eventsourcing.admin.sqlserver": [ - "README.md", - "lib/net10.0/Purview.EventSourcing.Admin.SqlServer.dll" + "lib/$(TFM)/Purview.EventSourcing.Admin.SqlServer.dll", + "lib/$(TFM)/Purview.EventSourcing.Admin.SqlServer.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.Admin.SqlServer.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.azurestorage": [ + "lib/$(TFM)/Purview.EventSourcing.AzureStorage.dll", + "lib/$(TFM)/Purview.EventSourcing.AzureStorage.xml", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.cosmosdb": [ + "lib/$(TFM)/Purview.EventSourcing.CosmosDb.dll", + "lib/$(TFM)/Purview.EventSourcing.CosmosDb.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.CosmosDb.xml", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.inmemory": [ + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "lib/$(TFM)/Purview.EventSourcing.InMemory.dll", + "lib/$(TFM)/Purview.EventSourcing.InMemory.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.mongodb": [ + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "lib/$(TFM)/Purview.EventSourcing.MongoDB.dll", + "lib/$(TFM)/Purview.EventSourcing.MongoDB.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.MongoDB.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.postgres": [ + "analyzers/dotnet/cs/Purview.EventSourcing.EntityFrameworkCore.SourceGenerator.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "lib/$(TFM)/Purview.EventSourcing.Postgres.dll", + "lib/$(TFM)/Purview.EventSourcing.Postgres.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.Postgres.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.sqlserver": [ + "analyzers/dotnet/cs/Purview.EventSourcing.EntityFrameworkCore.SourceGenerator.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.dll", + "lib/$(TFM)/Purview.EventSourcing.ImplementationShared.xml", + "lib/$(TFM)/Purview.EventSourcing.SqlServer.dll", + "lib/$(TFM)/Purview.EventSourcing.SqlServer.runtimeconfig.json", + "lib/$(TFM)/Purview.EventSourcing.SqlServer.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.validation.fluentvalidation": [ + "lib/$(TFM)/Purview.EventSourcing.Validation.FluentValidation.dll", + "lib/$(TFM)/Purview.EventSourcing.Validation.FluentValidation.xml", + "purview-logo-light.png", + "README.md" + ], + "purview.eventsourcing.validation.zodsharp": [ + "buildTransitive/Purview.EventSourcing.Validation.ZodSharp.targets", + "lib/$(TFM)/Purview.EventSourcing.Validation.ZodSharp.dll", + "lib/$(TFM)/Purview.EventSourcing.Validation.ZodSharp.xml", + "purview-logo-light.png", + "README.md" ] - }, - "ForbiddenContent": {} + } }, "Release": { "Mode": "None" diff --git a/src/EventSourcing.slnx b/src/EventSourcing.slnx index a341a0f1..f12d3af3 100644 --- a/src/EventSourcing.slnx +++ b/src/EventSourcing.slnx @@ -5,6 +5,7 @@ + @@ -58,10 +59,7 @@ - + @@ -69,10 +67,7 @@ - + diff --git a/src/src/Admin.API/Filters/ZodSchemaValidationEndpointFilter.cs b/src/src/Admin.API/Filters/ZodSchemaValidationEndpointFilter.cs index f5a7ed7d..8a293634 100644 --- a/src/src/Admin.API/Filters/ZodSchemaValidationEndpointFilter.cs +++ b/src/src/Admin.API/Filters/ZodSchemaValidationEndpointFilter.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Http; -using ZodSharp.AspNetCore; +using ZodSharp; using ZodSharp.Core; namespace Purview.EventSourcing.Admin.API.Filters; diff --git a/src/src/AzureStorage/TableEventStore.GetEventRangeAsync.cs b/src/src/AzureStorage/TableEventStore.GetEventRangeAsync.cs index 8a1783d7..cc7476c3 100644 --- a/src/src/AzureStorage/TableEventStore.GetEventRangeAsync.cs +++ b/src/src/AzureStorage/TableEventStore.GetEventRangeAsync.cs @@ -170,6 +170,7 @@ static UnknownEvent ReturnUnknownEvent(EventEntity eventEntity, int aggregateVer if (blobEvent == null) return null; + // Apply upcasting chain when a registry is available. return new EventRecord(blobEvent, metadata); } } @@ -177,6 +178,7 @@ static UnknownEvent ReturnUnknownEvent(EventEntity eventEntity, int aggregateVer if (@event == null) return null; + // Apply upcasting chain when a registry is available. return new EventRecord(@event, metadata); } #pragma warning disable CA1031 diff --git a/src/src/AzureStorage/TableEventStore.SaveOperation.cs b/src/src/AzureStorage/TableEventStore.SaveOperation.cs index 212bd7c6..1f300435 100644 --- a/src/src/AzureStorage/TableEventStore.SaveOperation.cs +++ b/src/src/AzureStorage/TableEventStore.SaveOperation.cs @@ -167,7 +167,7 @@ CancellationToken cancellationToken return (null, aggregate, operationContext, idempotencyId, changeEvents, isNew, idempotencyMarkerOperation); } - [System.Diagnostics.CodeAnalysis.SuppressMessage( + [SuppressMessage( "Maintainability", "CA1502:Avoid excessive complexity", Justification = "Save orchestration handles many interleaved states; keep the flow readable." diff --git a/src/src/Benchmarks/BenchmarkHistoryStore.cs b/src/src/Benchmarks/BenchmarkHistoryStore.cs index b15996a6..9b4bc69d 100644 --- a/src/src/Benchmarks/BenchmarkHistoryStore.cs +++ b/src/src/Benchmarks/BenchmarkHistoryStore.cs @@ -3,16 +3,14 @@ namespace Purview.EventSourcing.Benchmarks; -sealed class BenchmarkHistoryStore +sealed class BenchmarkHistoryStore(string mode) { static readonly JsonSerializerOptions SerializerOptions = new() { WriteIndented = true }; - readonly string _mode; + readonly string _mode = mode; readonly string _repositoryRoot = FindRepositoryRoot(); - public BenchmarkHistoryStore(string mode) => _mode = mode; - string HistoryDirectory => Path.Combine(_repositoryRoot, "artifacts", $"{_mode}-performance", "history"); string LatestPath => Path.Combine(_repositoryRoot, "artifacts", $"{_mode}-performance", "latest.json"); diff --git a/src/src/Benchmarks/Benchmarks.csproj b/src/src/Benchmarks/Benchmarks.csproj index 5f47d848..48e861cd 100644 --- a/src/src/Benchmarks/Benchmarks.csproj +++ b/src/src/Benchmarks/Benchmarks.csproj @@ -3,7 +3,7 @@ net10.0 enable enable - Purview.EventSourcing + Purview.EventSourcing.Benchmarks preview $(NoWarn);CA1303;CA1308;CA1707;CA1822;CA1515;CA1852; Exe diff --git a/src/src/Benchmarks/InMemoryPerformanceBenchmarks.cs b/src/src/Benchmarks/InMemoryPerformanceBenchmarks.cs index 80be4bfa..0391d9b0 100644 --- a/src/src/Benchmarks/InMemoryPerformanceBenchmarks.cs +++ b/src/src/Benchmarks/InMemoryPerformanceBenchmarks.cs @@ -1,7 +1,5 @@ -using System.Reflection; using BenchmarkDotNet.Attributes; using Purview.EventSourcing.Aggregates; -using Purview.EventSourcing.Aggregates.Events; using Purview.EventSourcing.ChangeFeed; using Purview.EventSourcing.InMemory.Events; using Purview.EventSourcing.Samples.Domain; @@ -57,6 +55,7 @@ public void GlobalSetup() 1.99m ); } + _store.SaveAsync(large, _operationContext).GetAwaiter().GetResult(); } diff --git a/src/src/Benchmarks/Program.cs b/src/src/Benchmarks/Program.cs index d9b21c49..3b799432 100644 --- a/src/src/Benchmarks/Program.cs +++ b/src/src/Benchmarks/Program.cs @@ -1,8 +1,12 @@ +#pragma warning disable format + using BenchmarkDotNet.Configs; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Running; using BenchmarkDotNet.Toolchains.InProcess.Emit; using Purview.EventSourcing.Benchmarks; +using Purview.EventSourcing.Benchmarks.SourceGenerator; +using Purview.EventSourcing.Benchmarks.SqlServer; // The suites run with the in-process toolchain: benchmarks execute directly in this process, which // avoids BenchmarkDotNet generating an out-of-process boilerplate project. The repository's diff --git a/src/src/Benchmarks/RuntimePerformanceBenchmarks.cs b/src/src/Benchmarks/RuntimePerformanceBenchmarks.cs index 3290e5ef..60904ffe 100644 --- a/src/src/Benchmarks/RuntimePerformanceBenchmarks.cs +++ b/src/src/Benchmarks/RuntimePerformanceBenchmarks.cs @@ -56,8 +56,11 @@ public void GlobalSetup() _moneyB = Money.Create(19.99m, CurrencyCode.Create("EUR")); _moneyJson = EventStoreSerializationHelpers.Serialize(_moneyA); - _orderCreatedEvent = new OrderCreatedEvent { CustomerId = "customer-1" }; - _orderCreatedEvent.Metadata = new EventMetadata(1, DateTimeOffset.UtcNow, 1, null, null, null, null); + _orderCreatedEvent = new OrderCreatedEvent + { + CustomerId = "customer-1", + Metadata = new EventMetadata(1, DateTimeOffset.UtcNow, 1, null, null, null, null), + }; _orderJson = EventStoreSerializationHelpers.Serialize(_orderCreatedEvent, _orderCreatedEvent.GetType()); _replayEvents = new EventRecord[100]; diff --git a/src/src/Benchmarks/SourceGeneratorPerformanceBenchmarks.cs b/src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceBenchmarks.cs similarity index 98% rename from src/src/Benchmarks/SourceGeneratorPerformanceBenchmarks.cs rename to src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceBenchmarks.cs index 94242503..72cd38d3 100644 --- a/src/src/Benchmarks/SourceGeneratorPerformanceBenchmarks.cs +++ b/src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceBenchmarks.cs @@ -2,9 +2,8 @@ using BenchmarkDotNet.Attributes; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Purview.EventSourcing.SourceGenerator; -namespace Purview.EventSourcing.Benchmarks; +namespace Purview.EventSourcing.Benchmarks.SourceGenerator; /// /// Measures how fast the aggregate and value-object generators run and, crucially, how well the diff --git a/src/src/Benchmarks/SourceGeneratorPerformanceScenarios.cs b/src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceScenarios.cs similarity index 99% rename from src/src/Benchmarks/SourceGeneratorPerformanceScenarios.cs rename to src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceScenarios.cs index 8b6c37ea..9a8c734f 100644 --- a/src/src/Benchmarks/SourceGeneratorPerformanceScenarios.cs +++ b/src/src/Benchmarks/SourceGenerator/SourceGeneratorPerformanceScenarios.cs @@ -1,7 +1,7 @@ using Microsoft.CodeAnalysis; using Purview.EventSourcing.SourceGenerator.Generators; -namespace Purview.EventSourcing.SourceGenerator; +namespace Purview.EventSourcing.Benchmarks.SourceGenerator; public sealed record SourceGeneratorScenario( string Name, diff --git a/src/src/Benchmarks/SqlServerPerformanceBenchmarks.cs b/src/src/Benchmarks/SqlServer/SqlServerPerformanceBenchmarks.cs similarity index 98% rename from src/src/Benchmarks/SqlServerPerformanceBenchmarks.cs rename to src/src/Benchmarks/SqlServer/SqlServerPerformanceBenchmarks.cs index 94124454..257c7054 100644 --- a/src/src/Benchmarks/SqlServerPerformanceBenchmarks.cs +++ b/src/src/Benchmarks/SqlServer/SqlServerPerformanceBenchmarks.cs @@ -9,13 +9,12 @@ using Purview.EventSourcing.Samples.Domain; using Purview.EventSourcing.Samples.ValueObjects; using Purview.EventSourcing.Services; -using Purview.EventSourcing.SqlServer; using Purview.EventSourcing.SqlServer.Events; using Purview.EventSourcing.SqlServer.Snapshot; using Purview.EventSourcing.SqlServer.Snapshots; using Testcontainers.MsSql; -namespace Purview.EventSourcing.Benchmarks; +namespace Purview.EventSourcing.Benchmarks.SqlServer; /// /// Measures event-store save/get and snapshot write/query timings against a SQL Server @@ -69,7 +68,7 @@ public void GlobalSetup() _eventStore = CreateEventStore(connectionString, $"PerfEvents_{runId}"); _snapshotStore = CreateSnapshotStore(_eventStore, connectionString, $"PerfSnapshots_{runId}"); - _seededIds = Enumerable.Range(0, _workload.AggregateCount).Select(static _ => $"{Guid.NewGuid():D}").ToArray(); + _seededIds = [.. Enumerable.Range(0, _workload.AggregateCount).Select(static _ => $"{Guid.NewGuid():D}")]; var loaded = new List(_seededIds.Length); for (var i = 0; i < _seededIds.Length; i++) @@ -158,12 +157,12 @@ public void GlobalSetup() } [GlobalCleanup] - public void GlobalCleanup() + public async Task GlobalCleanup() { EventStoreOperationContext.RequiresValidPrincipalIdentifierDefault = _previousRequiresPrincipal; if (_container is not null) - _container.DisposeAsync().AsTask().GetAwaiter().GetResult(); + await _container.DisposeAsync(); } [Benchmark] @@ -561,7 +560,7 @@ public static T Create() where T : class => DispatchProxy.Create(); } - class NoOpDispatchProxy : DispatchProxy + sealed class NoOpDispatchProxy : DispatchProxy { protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) { diff --git a/src/src/Benchmarks/SqlServerPerformanceWorkload.cs b/src/src/Benchmarks/SqlServer/SqlServerPerformanceWorkload.cs similarity index 76% rename from src/src/Benchmarks/SqlServerPerformanceWorkload.cs rename to src/src/Benchmarks/SqlServer/SqlServerPerformanceWorkload.cs index e64bd8db..030d0478 100644 --- a/src/src/Benchmarks/SqlServerPerformanceWorkload.cs +++ b/src/src/Benchmarks/SqlServer/SqlServerPerformanceWorkload.cs @@ -1,4 +1,4 @@ -namespace Purview.EventSourcing.SqlServer; +namespace Purview.EventSourcing.Benchmarks.SqlServer; sealed class SqlServerPerformanceWorkload { diff --git a/src/src/EventSourcing/Aggregates/AggregateBase.cs b/src/src/EventSourcing/Aggregates/AggregateBase.cs index f46830e0..8c4d1297 100644 --- a/src/src/EventSourcing/Aggregates/AggregateBase.cs +++ b/src/src/EventSourcing/Aggregates/AggregateBase.cs @@ -234,6 +234,7 @@ IEnumerable IAggregate.GetRegisteredEventTypes() if (_customAppliers is not null) return _customAppliers.Keys; + // No events registered, return empty list. return []; } @@ -268,6 +269,7 @@ Action GetApplier(Type eventType) if (_customAppliers is not null && _customAppliers.TryGetValue(eventType, out applier)) return applier; + // No applier found for the event type. throw new UnregisteredEventException(eventType, this); } diff --git a/src/src/InMemory/Events/InMemoryEventStore.ExceptionHelpers.cs b/src/src/InMemory/Events/InMemoryEventStore.ExceptionHelpers.cs index c4a9c118..1b342299 100644 --- a/src/src/InMemory/Events/InMemoryEventStore.ExceptionHelpers.cs +++ b/src/src/InMemory/Events/InMemoryEventStore.ExceptionHelpers.cs @@ -1,4 +1,4 @@ -namespace Purview.EventSourcing.InMemory.Events; +namespace Purview.EventSourcing.InMemory.Events; [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter")] partial class InMemoryEventStore diff --git a/src/src/MongoDB/Events/MongoDBEventStore.GetEventRangeAsync.cs b/src/src/MongoDB/Events/MongoDBEventStore.GetEventRangeAsync.cs index 554d216e..954445d7 100644 --- a/src/src/MongoDB/Events/MongoDBEventStore.GetEventRangeAsync.cs +++ b/src/src/MongoDB/Events/MongoDBEventStore.GetEventRangeAsync.cs @@ -123,6 +123,7 @@ static UnknownEvent ReturnUnknownEvent(EventEntity eventEntity, int aggregateVer if (@event == null) return null; + // If the upcasted event is of a different type than the original, log it. return new EventRecord(@event, metadata); } #pragma warning disable CA1031 diff --git a/src/src/Postgres/Events/Exceptions/AggregateAlreadyDeletedException.cs b/src/src/Postgres/Events/Exceptions/AggregateAlreadyDeletedException.cs index de3bddea..b2bc4ccc 100644 --- a/src/src/Postgres/Events/Exceptions/AggregateAlreadyDeletedException.cs +++ b/src/src/Postgres/Events/Exceptions/AggregateAlreadyDeletedException.cs @@ -1,6 +1,7 @@ +#pragma warning disable CA1032 // Implement standard exception constructors + namespace Purview.EventSourcing.Postgres.Events.Exceptions; -#pragma warning disable CA1032 // Implement standard exception constructors /// /// Thrown when an attempt is made to delete an aggregate that has already been deleted. /// @@ -10,7 +11,6 @@ public class AggregateAlreadyDeletedException(string aggregateId, string idempot : Exception( $"An attempt to delete an aggregate (Id: {aggregateId}) that is already deleted was made. {nameof(idempotencyId)}: {idempotencyId}." ) -#pragma warning restore CA1032 // Implement standard exception constructors { /// /// The id of the aggregate that is already deleted. diff --git a/src/src/Postgres/Events/Exceptions/AggregateDeletedException.cs b/src/src/Postgres/Events/Exceptions/AggregateDeletedException.cs index 896ab674..90e089c0 100644 --- a/src/src/Postgres/Events/Exceptions/AggregateDeletedException.cs +++ b/src/src/Postgres/Events/Exceptions/AggregateDeletedException.cs @@ -1,6 +1,7 @@ +#pragma warning disable CA1032 // Implement standard exception constructors + namespace Purview.EventSourcing.Postgres.Events.Exceptions; -#pragma warning disable CA1032 // Implement standard exception constructors /// /// Thrown when an attempt is made to save an aggregate that has been deleted. /// @@ -10,7 +11,6 @@ public class AggregateDeletedException(string aggregateId, string idempotencyId) : Exception( $"An attempt to save an aggregate that has been deleted, aggregate Id: {aggregateId}, {nameof(IdempotencyId)}: {idempotencyId}." ) -#pragma warning restore CA1032 // Implement standard exception constructors { /// /// The id of the deleted aggregate. diff --git a/src/src/Postgres/Events/PostgresEventStore.GetEventRangeAsync.cs b/src/src/Postgres/Events/PostgresEventStore.GetEventRangeAsync.cs index f5f0a66b..08b5051e 100644 --- a/src/src/Postgres/Events/PostgresEventStore.GetEventRangeAsync.cs +++ b/src/src/Postgres/Events/PostgresEventStore.GetEventRangeAsync.cs @@ -106,6 +106,7 @@ static UnknownEvent ReturnUnknownEvent(PostgresEventStoreClient.RowData eventRow if (@event == null) return null; + // If the event is an UnknownEvent, we still want to return it, but we also want to log that we couldn't deserialize it. return new EventRecord(@event, metadata); } #pragma warning disable CA1031 diff --git a/src/src/Postgres/Events/PostgresEventStore.SaveAsync.cs b/src/src/Postgres/Events/PostgresEventStore.SaveAsync.cs index 46b71c21..7d5e7e5a 100644 --- a/src/src/Postgres/Events/PostgresEventStore.SaveAsync.cs +++ b/src/src/Postgres/Events/PostgresEventStore.SaveAsync.cs @@ -106,7 +106,7 @@ params EventRecord[] additionalEvents var isNew = aggregate.IsNew(); var changeEvents = (additionalEvents?.Length ?? 0) == 0 - ? aggregate.GetUnsavedEvents().ToArray() + ? [.. aggregate.GetUnsavedEvents()] : aggregate.GetUnsavedEvents().Concat(additionalEvents!).ToArray(); if (changeEvents.Length > _eventStoreOptions.Value.MaxEventCountOnSave) @@ -158,7 +158,7 @@ params EventRecord[] additionalEvents ); } - [System.Diagnostics.CodeAnalysis.SuppressMessage( + [SuppressMessage( "Maintainability", "CA1502:Avoid excessive complexity", Justification = "Save orchestration handles many interleaved states; keep the flow readable." diff --git a/src/src/SourceGenerator/Aggregate/AggregateSourceEmitter.cs b/src/src/SourceGenerator/Aggregate/AggregateSourceEmitter.cs index a7533f07..96d59476 100644 --- a/src/src/SourceGenerator/Aggregate/AggregateSourceEmitter.cs +++ b/src/src/SourceGenerator/Aggregate/AggregateSourceEmitter.cs @@ -115,7 +115,7 @@ static void GenerateRegisterEvents(AggregateEmitContext outputContext, CodeWrite { bodyWriter.MethodCall( "RegisterGenerated", - System.Array.Empty(), + Array.Empty(), genericArguments: [method.EventType] ); } diff --git a/src/src/SourceGenerator/Generators/AggregateSourceGenerator.cs b/src/src/SourceGenerator/Generators/AggregateSourceGenerator.cs index 44c8bf67..d136a9f9 100644 --- a/src/src/SourceGenerator/Generators/AggregateSourceGenerator.cs +++ b/src/src/SourceGenerator/Generators/AggregateSourceGenerator.cs @@ -19,8 +19,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // short-circuits instead of re-executing every aggregate transform (see PreCompilationMarker). #pragma warning disable RSEXPERIMENTAL007 // Pre-compilation source output is intentionally used to stabilize the incremental cache. context.RegisterPreCompilationSourceOutput( - Common.PreCompilationMarker.Provider(context), - static (spc, source) => spc.AddSource(Common.PreCompilationMarker.HintName, source) + PreCompilationMarker.Provider(context), + static (spc, source) => spc.AddSource(PreCompilationMarker.HintName, source) ); #pragma warning restore RSEXPERIMENTAL007 diff --git a/src/src/SqlServer/Events/SqlServerEventStore.GetEventRangeAsync.cs b/src/src/SqlServer/Events/SqlServerEventStore.GetEventRangeAsync.cs index e462ec25..8151319d 100644 --- a/src/src/SqlServer/Events/SqlServerEventStore.GetEventRangeAsync.cs +++ b/src/src/SqlServer/Events/SqlServerEventStore.GetEventRangeAsync.cs @@ -106,6 +106,7 @@ static UnknownEvent ReturnUnknownEvent(SqlServerEventStoreClient.RowData eventRo if (@event == null) return null; + // If the event is an IEvent, we can return it directly. Otherwise, we wrap it in an UnknownEvent. return new EventRecord(@event, metadata); } #pragma warning disable CA1031 diff --git a/src/src/SqlServer/Events/SqlServerEventStore.SaveAsync.cs b/src/src/SqlServer/Events/SqlServerEventStore.SaveAsync.cs index 4710b2d0..6ed6286c 100644 --- a/src/src/SqlServer/Events/SqlServerEventStore.SaveAsync.cs +++ b/src/src/SqlServer/Events/SqlServerEventStore.SaveAsync.cs @@ -106,7 +106,7 @@ params EventRecord[] additionalEvents var isNew = aggregate.IsNew(); var changeEvents = (additionalEvents?.Length ?? 0) == 0 - ? aggregate.GetUnsavedEvents().ToArray() + ? [.. aggregate.GetUnsavedEvents()] : aggregate.GetUnsavedEvents().Concat(additionalEvents!).ToArray(); if (changeEvents.Length > _eventStoreOptions.Value.MaxEventCountOnSave) @@ -158,7 +158,7 @@ params EventRecord[] additionalEvents ); } - [System.Diagnostics.CodeAnalysis.SuppressMessage( + [SuppressMessage( "Maintainability", "CA1502:Avoid excessive complexity", Justification = "Save orchestration handles many interleaved states; keep the flow readable." diff --git a/src/tests/CosmosDb.IntegrationTests/Snapshots/CosmosDbSnapshotEventStoreTests.WithStringValues.cs b/src/tests/CosmosDb.IntegrationTests/Snapshots/CosmosDbSnapshotEventStoreTests.WithStringValues.cs index be4719b5..7bf90a4f 100644 --- a/src/tests/CosmosDb.IntegrationTests/Snapshots/CosmosDbSnapshotEventStoreTests.WithStringValues.cs +++ b/src/tests/CosmosDb.IntegrationTests/Snapshots/CosmosDbSnapshotEventStoreTests.WithStringValues.cs @@ -1,4 +1,4 @@ -using Microsoft.Azure.Cosmos; +using Microsoft.Azure.Cosmos; using Microsoft.Extensions.Primitives; using Purview.EventSourcing.Aggregates.Persistence; diff --git a/src/tests/EventSourcing.UnitTests/Serialization/EventStoreSerializationHelpersTests.cs b/src/tests/EventSourcing.UnitTests/Serialization/EventStoreSerializationHelpersTests.cs index 188bb404..6f1c67ab 100644 --- a/src/tests/EventSourcing.UnitTests/Serialization/EventStoreSerializationHelpersTests.cs +++ b/src/tests/EventSourcing.UnitTests/Serialization/EventStoreSerializationHelpersTests.cs @@ -60,7 +60,7 @@ public async Task SerializeAndDeserialize_GivenEventWithMetadata_DoesNotSerializ await Assert.That(roundTripped).IsNotNull(); await Assert.That(roundTripped!.Value).IsEqualTo("event-value"); - await Assert.That(roundTripped.Metadata).IsEqualTo(default(EventMetadata)); + await Assert.That(roundTripped.Metadata).IsEqualTo(default); using var document = JsonDocument.Parse(json); await Assert.That(document.RootElement.TryGetProperty("Metadata", out _)).IsFalse(); diff --git a/src/tests/SourceGenerator.UnitTests/Common/EventSourcingGeneratorTestOptions.cs b/src/tests/SourceGenerator.UnitTests/Common/EventSourcingGeneratorTestOptions.cs index fcbf34dc..3b37ada4 100644 --- a/src/tests/SourceGenerator.UnitTests/Common/EventSourcingGeneratorTestOptions.cs +++ b/src/tests/SourceGenerator.UnitTests/Common/EventSourcingGeneratorTestOptions.cs @@ -1,3 +1,6 @@ +using Purview.ValueObjects; +using Purview.ValueObjects.Serialization; + namespace Purview.EventSourcing.SourceGenerator.Common; public record EventSourcingGeneratorTestOptions : SourceGeneratorTestOptions @@ -26,10 +29,10 @@ public EventSourcingGeneratorTestOptions() [ typeof(EventStoreSet<>).Namespace!, typeof(Aggregates.AggregateBase).Namespace!, - typeof(Purview.ValueObjects.Serialization.ScalarJsonConverterFactory).Namespace!, - typeof(Purview.ValueObjects.IValueObject).Namespace!, + typeof(ScalarJsonConverterFactory).Namespace!, + typeof(IValueObject).Namespace!, ]; - AdditionalAssemblyTypes = [typeof(Aggregates.IAggregate), typeof(Purview.ValueObjects.IValueObject)]; + AdditionalAssemblyTypes = [typeof(Aggregates.IAggregate), typeof(IValueObject)]; AdditionalReferences = [.. TestMetadataReferences.GetAdditionalReferences()]; ExcludeGeneratedSourceHintNames = [.. AggregateGeneratedAttributes, PreCompilationMarkerHintName]; AnalyzerTypes = [typeof(Analyzers.AggregateDiagnosticAnalyzer)];